UNIX进程间通信课件_第1页
UNIX进程间通信课件_第2页
UNIX进程间通信课件_第3页
UNIX进程间通信课件_第4页
UNIX进程间通信课件_第5页
已阅读5页,还剩27页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

UNIX进程间通信第一节进程通信的基本概念进程通信包括控制信息传递和大批量信息传递.1.通信方式1)主从式-----通信进程间有主从之分。2)会话式-----用请求/服务方式完成通信。3)平等方式——通过消息缓冲或邮箱完成通信;或通过共享缓冲区通信。2.Unix中的进程通信基本通信:用于传递进程间的控制信息;管道通信:将管道文件作为通信的介质,传递进程间的信息;IPC(InterProcessCommuation)通信:用于进程间大量的数据传送。第二节UNIX的基本进程通信锁文件通信通信进程双方在某个指定目录中(通常会是/tmp目录)查找是否有一个双方约定好的锁文件存在,存在时完成一种处理,不存在时完成另一种操作。记录锁定文件通信记录文件中连续存储的字节组成的特定数据段或数据区。实现:使用UNIX中已有的一个加锁程序。方式建议型锁定强制型锁定常用操作方法:系统调用fcntl及库函数lockf3.信号通信信号进程中异步发生事件的提示信息。UNIX进程通信中可使用的信号已做了预先的内部约定。查看各信号的描述说明:man命令或在头文件<sys/signal.h>中。信号的作用用于进程间的同步和互斥进程的条件执行信号的发送编程级的:系统调用kill(pid,sig)Shell命令级的:kill命令注:普通用户只能向自己创建的进程发送信号;超户可以向任意进程发送信号。信号的捕获和处理系统调用signal(sig,func())功能:为sig信号注册指定的处理函数func三种取值:SIG-IGN:忽略所接收信号SIG-DFL:恢复对信号的缺省处理函数名:自定义函数/*test_signal.c*/#include<signal.h>main(){voidcatchint();

inti;

signal(SIGINT,catchint());for(i=1;i<5;i++){printf(“sleepcall#%d\n”,i);

sleep(1);}

printf(“Exiting.\n”);exit(0);}voidcatchint(intsigno){/*signal(SIGINT,SIG_IGN);*/

printf(“\nCATCHINT:signo=%d;”,signo);

printf(“Return.\n”);}1)执行中不用delete或^c键打断%test_signalsleepcall#1……sleepcall#4Exiting./*test_signal.c*/#include<signal.h>main(){voidcatchint();

inti;signal(SIGINT,catchint());for(i=1;i<5;i++){printf(“sleepcall#%d\n”,i);

sleep(1);}

printf(“Exiting.\n”);exit(0);}voidcatchint(intsigno){

printf(“\nCATCHINT:signo=%d;”,signo);

printf(“Return.\n”);}2)在第二次循环后按了delete键;%test_signalsleepcall#1sleepcall#2CATCHINT:signo=2;Return.sleepcall#3sleepcall#4Exiting./*test_signal.c*/#include<signal.h>main(){voidcatchint();

inti;signal(SIGINT,catchint());for(i=1;i<5;i++){printf(“sleepcall#%d\n”,i);

sleep(1);}

printf(“Exiting.\n”);exit(0);}voidcatchint(intsigno){

printf(“\nCATCHINT:signo=%d;”,signo);

printf(“Return.\n”);}3)第二次循环后按了delete键,第三次又按了delete键。%test_signalsleepcall#1sleepcall#2CATCHINT:signo=2;Return.sleepcall#3

signal(SIGINT,catchint());信号复位:信号处理函数仅用一次,处理过一次后恢复到默认处理程序状态。第三节管道通信管道UNIX中的一种先进先出(FIFO)的特殊文件管道的读写依然使用read、write系统调用管道读出写入写管道与写文件的区别写管道总在管道的末尾写;写文件可以通过调整文件指针在任意位置写。写管道每次写入的字节数受系统参数限制。设备忙时,write会被阻塞延迟执行。写一个没有以写方式打开的管道,将生成SIGPIPE信号,error置为EPIPE。读管道与读文件的区别读管道总从管道的当前位置读;读文件支持文件指针的移动。当管道中无信息时read系统调用被阻塞;读空文件返回空串。若管道未被其他进程以写方式打开,就对管道进行read,返回0值。无名管道创建方法:Shell命令级的:|管道符编程级的:intfds[2];

intpipe(fds);使用fds[0]读取管道中的数据;使用fds[1]往管道中写入数据。应用场合:父子进程间通信示例/*用管道将数据从父进程传递到子进程*/#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<sting.h>#defineBUFSIZ512main(intargc,char*argv[]){int

fds[2];staticcharmessage[BUFSIZ];if(argc!=2){

fprintf(stderr,”Usage:%smessage\n”,*argv);

exit(1);}if(pipe(fds)==-1){

perror(“pipe”);exit(2);}switch(fork()){case-1:perror(“forkerror.”);

exit(3);case0:close(fds[1]);

if(read(fds[0],message,BUFSIZ)!=-1){ printf(“Messagereceivedbychild:[%s]\n”,message); fflush(stdout); }else{perror(“Readerror”); exit(4); } break;default:

close(fds[0]);

if(write(fds[1],argv[1],strlen(argv[1]))!=-1){printf("Messagesentbyparent:[%s]\n",argv[1]);

fflush(stdout);

}else{

perror("write");

exit(5);}

}exit(0);}%a.out"messageisabc"Messagereceivedbychild:[messageisabc]Messagesentbyparent:[messageisabc]有名管道特点生成时在文件系统中生成一个目录表项;允许两个独立的进程借此进行通信。创建方法:shell命令级的:mknod命令例:%mknodPFILEp管道文件名表示生成一个管道文件创建方法(续)库函数popen()

管道文件名访问权限典型用法:……mknod(path,S_IFIFO|mode,0);……fd=open(path,0);……read(fd,buf,PIPE_BUF);……编程级的:系统调用mknod()第四节SystemVIPCSystemVIPC的三种通信机制消息队列(messagequeue)进程间分类格式化的数据传送。共享内存(sharedmemory)通过共享同一块内存空间实现进程间通信。信号灯(semaphore)多个进程在一组信号灯上同步。相关知识IPC标识符每个SystemVIPC对象都有一个,对本类IPC对象唯一。key_t键三种类型的SystemVIPC使用key_t值作为它们的名字;<sys/types.h>把key_t定义为一个整数,通常由一个进程相关或用户相关的唯一的字符串通过ftok函数生成。内核中的消息队列结构消息机制提供的系统调用msgget:返回消息描述符,用于创建或指定一消息队列msgqid=msgget(key,msgflg)key_tkey;/*关键字*/intmsgflg;/*get的标志及许可权*/msgsnd:发送消息,成功返回0,出错为-1msgsnd(msgqid,msgp,msgsz,msgflg)intmsgqid;/*消息描述符*/structmsgbuf*msgp;

/*消息类型和字符数组的指针*/intmsgsz,msgflg;/*

msgsz是数组大小,msgflg是同步标识*/msgrcv:接受消息msgrcv(msgqid,msgp,msgsz,msgtype,msgflg)intmsgqid;structmsgbug*msgp;intmsgsz;longmsgtype;

/*用户想要读出消息的类型*/intmsgflg;msgctl:查询、设置或删除消息描述符的状态msgctl(msgqid,cmd,buf)intmsgqid,cmd;/*cmd是规定命令的类型:IPC_STAT、IPC_SET或IPC_RMID*/msgqid_ds*buf;/*用户数据结构的地址*/相关的头文件:sys/types.h sys/ipc.h sys/msg.h相关管理命令ipcs命令ipcrm命令系统调用的使用关系和顺序:首先用msgget建立或打开一个消息队列,得到msgqid。例:msgqid=msgget(MSGKEY,0777)然后,用上述获得的msgqid调用msgsnd和msgrcv发送和接受消息。或,调用msgctl

来设置或获取消息队列属性、或删除该消息队列。例:客户进程和服务进程用消息机制进行信息通信/*msg-client.c*/#include<sys/types.h>#include<sys/ipc.h>#include<sys/msg.h>#defineMSGKEY75structmsgform{longmtype;charmtext[256];};main(){structmsgformmsg;

intmsgqid,pid,*pint;

msgqid=msgget(MSGKEY,0777);pid=getpid();printf(“client:pid=%d\n”,pid);pint=(int*)msg.mtext;*pint=pid;msg.mtype=1;msgsnd(msgqid,&msg,sizeof(int),0);msgrcv(msgqid,&msg,256,pid,0);printf(“client:receivefrompid%d\n”,*pint);}/*msg-server.c*/#inclide<sys/types.h>#inclide<sys/ipc.h>#inclide<sys/msg.h>#defineMSGKEY75structmsgform{longmtype;charmtext[256];}msg;

intmsgqid;main(){inti,pid,*pint;externcleanup();for(i=0;i<23;i++)signal(i,cleanup);sgqid=msgget(MSGKEY,0777|IPC_CREAT);

printf(“server:pid=%d\n”,getpid());for(;;){

msgrcv(msgqid,&msg,256,1,0);pint=(int*)msg.mtext;pid=*pint;

printf(“server:receivefrompid%d\n”,pid);msg.mtype=pid;*pint=getpid();

sgsnd(msgqid,&msg,sizeof(int),0);

}}cleanup(

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论