⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 [ 永远的unix linux下c语言编程--进程通信、消息管理 ].htm

📁 描述unix,linux下进程间通信方式
💻 HTM
📖 第 1 页 / 共 2 页
字号:
            <BR>while(((semop_ret=semop(semid,&amp;semsignal,1))==-1)&amp;&amp;(errno==EINTR)); 
            <BR>if(semop_ret==-1) 
            <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            fprintf(stderr,"[%d]:Increment&nbsp;Semaphore&nbsp;Error:%s\n\a", 
            <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getpid(),strerror(errno)); 
            <BR>&nbsp;} <BR><BR>/* 不能够在其他进程反问信号灯的时候,我们删除了信号灯 */ 
            <BR>while((wait(&amp;status)==-1)&amp;&amp;(errno==EINTR)); <BR>/* 
            信号灯只能够被删除一次的 */ <BR>if(i==1) <BR>&nbsp;if(del_semaphore(semid)==-1) 
            <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,"[%d]:Destroy&nbsp;Semaphore&nbsp;Error:%s\n\a", 
            <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getpid(),strerror(errno)); 
            <BR>exit(0); <BR>}&nbsp; 
            <BR><BR>信号灯的主要用途是保护临界资源(在一个时刻只被一个进程所拥有).&nbsp; 
            <BR>3。SystemV消息队列&nbsp;为了便于进程之间通信,我们可以使用管道通信&nbsp;SystemV也提供了一些函数来实现进程的通信.这就是消息队列.&nbsp; 
            <BR><BR>&nbsp;&nbsp;#include&nbsp;<SYS types.h> 
            <BR>&nbsp;&nbsp;#include&nbsp;<SYS ipc.h> 
            <BR>&nbsp;&nbsp;#include&nbsp;<SYS msg.h> 
            <BR><BR>&nbsp;&nbsp;int&nbsp;msgget(key_t&nbsp;key,int&nbsp;msgflg); 
            <BR>&nbsp;&nbsp;int&nbsp;msgsnd(int&nbsp;msgid,struct&nbsp;msgbuf&nbsp;*msgp,int&nbsp;msgsz,int&nbsp;msgflg); 
            <BR>&nbsp;&nbsp;int&nbsp;msgrcv(int&nbsp;msgid,struct&nbsp;msgbuf&nbsp;*msgp,int&nbsp;msgsz, 
            <BR>long&nbsp;msgtype,int&nbsp;msgflg); 
            <BR>&nbsp;&nbsp;int&nbsp;msgctl(Int&nbsp;msgid,int&nbsp;cmd,struct&nbsp;msqid_ds&nbsp;*buf); 
            <BR><BR>struct msgbuf&nbsp;{ 
            <BR>long&nbsp;msgtype;&nbsp;&nbsp;&nbsp;/* 消息类型 */ <BR>....... /* 
            其他数据类型 */ <BR>} 
            <BR><BR>msgget函数和semget一样,返回一个消息队列的标志.msgctl和semctl是对消息进行控制.&nbsp;msgsnd和msgrcv函数是用来进行消息通讯的.msgid是接受或者发送的消息队列标志.&nbsp;msgp是接受或者发送的内容.msgsz是消息的大小.&nbsp;结构msgbuf包含的内容是至少有一个为msgtype.其他的成分是用户定义的.对于发送函数msgflg指出缓冲区用完时候的操作.接受函数指出无消息时候的处理.一般为0.&nbsp;接收函数msgtype指出接收消息时候的操作.&nbsp; 
            <BR>如果msgtype=0,接收消息队列的第一个消息.大于0接收队列中消息类型等于这个值的第一个消息.小于0接收消息队列中小于或者等于msgtype绝对值的所有消息中的最小一个消息.&nbsp;我们以一个实例来解释进程通信.下面这个程序有server和client组成.先运行服务端后运行客户端.&nbsp; 
            <BR>服务端&nbsp;server.c <BR><BR>#include&nbsp;<STDIO.H> 
            <BR>#include&nbsp;<STRING.H> <BR>#include&nbsp;<STDLIB.H> 
            <BR>#include&nbsp;<ERRNO.H> <BR>#include&nbsp;<UNISTD.H> 
            <BR>#include&nbsp;<SYS types.h> <BR>#include&nbsp;<SYS ipc.h> 
            <BR>#include&nbsp;<SYS stat.h> <BR>#include&nbsp;<SYS msg.h> 
            <BR><BR>#define&nbsp;&nbsp;&nbsp;MSG_FILE "server.c" <BR>#define 
            &nbsp;&nbsp;BUFFER 255 <BR>#define&nbsp;&nbsp;&nbsp;PERM 
            S_IRUSR|S_IWUSR <BR><BR>struct&nbsp;msgtype&nbsp;{ 
            <BR>long&nbsp;mtype; <BR>char&nbsp;buffer[BUFFER+1]; <BR>}; 
            <BR><BR>int&nbsp;main() <BR>{ 
            <BR>&nbsp;&nbsp;&nbsp;struct&nbsp;msgtype&nbsp;msg; 
            <BR>&nbsp;&nbsp;&nbsp;key_t&nbsp;key; 
            <BR>&nbsp;&nbsp;&nbsp;int&nbsp;msgid; <BR>&nbsp;&nbsp;&nbsp; 
            <BR>&nbsp;&nbsp;&nbsp;if((key=ftok(MSG_FILE,'a'))==-1) 
            <BR>&nbsp;&nbsp;&nbsp;&nbsp;{ 
            <BR>fprintf(stderr,"Creat&nbsp;Key&nbsp;Error:%s\a\n",strerror(errno)); 
            <BR>exit(1); <BR>&nbsp;&nbsp;&nbsp;&nbsp;} <BR>&nbsp;&nbsp; 
            <BR>&nbsp;&nbsp;if((msgid=msgget(key,PERM|IPC_CREAT|IPC_EXCL))==-1) 
            <BR>&nbsp;&nbsp;&nbsp;&nbsp;{ 
            <BR>fprintf(stderr,"Creat&nbsp;Message&nbsp;&nbsp;Error:%s\a\n",strerror(errno)); 
            <BR>exit(1); <BR>&nbsp;&nbsp;&nbsp;&nbsp;} <BR>&nbsp;&nbsp; 
            <BR>&nbsp;&nbsp;while(1) <BR>&nbsp;&nbsp;&nbsp;{ 
            <BR>msgrcv(msgid,&amp;msg,sizeof(struct&nbsp;msgtype),1,0); 
            <BR>fprintf(stderr,"Server&nbsp;Receive:%s\n",msg.buffer); 
            <BR>msg.mtype=2; 
            <BR>msgsnd(msgid,&amp;msg,sizeof(struct&nbsp;msgtype),0); 
            <BR>&nbsp;&nbsp;&nbsp;} <BR>&nbsp;&nbsp;exit(0); <BR>} 
            <BR><BR><BR>-------------------------------------------------------------------------------- 
            <BR><BR>客户端(client.c) <BR><BR>#include&nbsp;<STDIO.H> 
            <BR>#include&nbsp;<STRING.H> <BR>#include&nbsp;<STDLIB.H> 
            <BR>#include&nbsp;<ERRNO.H> <BR>#include&nbsp;<SYS types.h> 
            <BR>#include&nbsp;<SYS ipc.h> <BR>#include&nbsp;<SYS msg.h> 
            <BR>#include&nbsp;<SYS stat.h> <BR>#define&nbsp;&nbsp;&nbsp;MSG_FILE 
            "server.c" <BR>#define &nbsp;&nbsp;BUFFER 255 
            <BR>#define&nbsp;&nbsp;&nbsp;PERM S_IRUSR|S_IWUSR 
            <BR><BR>struct&nbsp;msgtype&nbsp;{ <BR>long&nbsp;mtype; 
            <BR>char&nbsp;buffer[BUFFER+1]; <BR>}; 
            <BR><BR>int&nbsp;main(int&nbsp;argc,char&nbsp;**argv) <BR>{ 
            <BR>&nbsp;&nbsp;&nbsp;struct&nbsp;msgtype&nbsp;msg; 
            <BR>&nbsp;&nbsp;&nbsp;key_t&nbsp;key; 
            <BR>&nbsp;&nbsp;&nbsp;int&nbsp;msgid; <BR>&nbsp;&nbsp;&nbsp; 
            <BR>&nbsp;&nbsp;&nbsp;if(argc!=2) <BR>&nbsp;&nbsp;&nbsp;&nbsp;{ 
            <BR>fprintf(stderr,"Usage:%s&nbsp;string\n\a",argv[0]); <BR>exit(1); 
            <BR>&nbsp;&nbsp;&nbsp;&nbsp;} 
            <BR><BR>&nbsp;&nbsp;&nbsp;if((key=ftok(MSG_FILE,'a'))==-1) 
            <BR>&nbsp;&nbsp;&nbsp;&nbsp;{ 
            <BR>fprintf(stderr,"Creat&nbsp;Key&nbsp;Error:%s\a\n",strerror(errno)); 
            <BR>exit(1); <BR>&nbsp;&nbsp;&nbsp;&nbsp;} <BR>&nbsp;&nbsp; 
            <BR>&nbsp;&nbsp;if((msgid=msgget(key,PERM))==-1) 
            <BR>&nbsp;&nbsp;&nbsp;&nbsp;{ 
            <BR>fprintf(stderr,"Creat&nbsp;Message&nbsp;&nbsp;Error:%s\a\n",strerror(errno)); 
            <BR>exit(1); <BR>&nbsp;&nbsp;&nbsp;&nbsp;} 
            <BR><BR>&nbsp;&nbsp;msg.mtype=1; 
            <BR>&nbsp;&nbsp;strncpy(msg.buffer,argv[1],BUFFER); 
            <BR>&nbsp;&nbsp;msgsnd(msgid,&amp;msg,sizeof(struct&nbsp;msgtype),0);&nbsp; 
            <BR>&nbsp;&nbsp;memset(&amp;msg,'\0',sizeof(struct&nbsp;msgtype)); 
            <BR>&nbsp;&nbsp;msgrcv(msgid,&amp;msg,sizeof(struct&nbsp;msgtype),2,0); 
            <BR>&nbsp;&nbsp;fprintf(stderr,"Client&nbsp;receive:%s\n",msg.buffer); 
            <BR>&nbsp;&nbsp;exit(0); <BR>}&nbsp;&nbsp; 
            <BR><BR>注意服务端创建的消息队列最后没有删除,我们要使用ipcrm命令来删除的.&nbsp; 
            <BR>4。SystemV共享内存&nbsp;还有一个进程通信的方法是使用共享内存.SystemV提供了以下几个函数以实现共享内存.&nbsp; 
            <BR><BR>#include&nbsp;<SYS types.h> <BR>#include&nbsp;<SYS ipc.h> 
            <BR>#include&nbsp;<SYS shm.h> 
            <BR><BR>int&nbsp;shmget(key_t&nbsp;key,int&nbsp;size,int&nbsp;shmflg); 
            <BR>void&nbsp;*shmat(int&nbsp;shmid,const&nbsp;void&nbsp;*shmaddr,int&nbsp;shmflg); 
            <BR>int&nbsp;shmdt(const&nbsp;void&nbsp;*shmaddr); 
            <BR>int&nbsp;shmctl(int&nbsp;shmid,int&nbsp;cmd,struct&nbsp;shmid_ds&nbsp;*buf); 
            <BR><BR>shmget和shmctl没有什么好解释的.size是共享内存的大小.&nbsp;shmat是用来连接共享内存的.shmdt是用来断开共享内存的.不要被共享内存词语吓倒,共享内存其实很容易实现和使用的.shmaddr,shmflg我们只要用0代替就可以了.在使用一个共享内存之前我们调用shmat得到共享内存的开始地址,使用结束以后我们使用shmdt断开这个内存.&nbsp; 
            <BR><BR>#include&nbsp;<STDIO.H> <BR>#include&nbsp;<STRING.H> 
            <BR>#include&nbsp;<ERRNO.H> <BR>#include&nbsp;<UNISTD.H> 
            <BR>#include&nbsp;<SYS stat.h> <BR>#include&nbsp;<SYS types.h> 
            <BR>#include&nbsp;<SYS ipc.h> <BR>#include&nbsp;<SYS shm.h> 
            <BR><BR>#define&nbsp;PERM S_IRUSR|S_IWUSR 
            <BR><BR>int&nbsp;main(int&nbsp;argc,char&nbsp;**argv) <BR>{ 
            <BR>&nbsp; <BR>&nbsp;int&nbsp;shmid; 
            <BR>&nbsp;char&nbsp;*p_addr,*c_addr; <BR>&nbsp;if(argc!=2) 
            <BR>&nbsp;&nbsp;{ <BR>fprintf(stderr,"Usage:%s\n\a",argv[0]); 
            <BR>exit(1); <BR>&nbsp;&nbsp;} 
            <BR><BR>&nbsp;if((shmid=shmget(IPC_PRIVATE,1024,PERM))==-1) 
            <BR>&nbsp;&nbsp;{ 
            <BR>fprintf(stderr,"Create&nbsp;Share&nbsp;Memory&nbsp;Error:%s\n\a",strerror(errno)); 
            <BR>exit(1); <BR>&nbsp;&nbsp;} <BR>&nbsp;if(fork()) 
            <BR>&nbsp;&nbsp;{ <BR>p_addr=shmat(shmid,0,0); 
            <BR>memset(p_addr,'\0',1024); <BR>strncpy(p_addr,argv[1],1024); 
            <BR>exit(0); <BR>&nbsp;&nbsp;} <BR>&nbsp;else <BR>&nbsp;&nbsp;{ 
            <BR>c_addr=shmat(shmid,0,0); 
            <BR>printf("Client&nbsp;get&nbsp;%s",c_addr); <BR>exit(0); 
            <BR>&nbsp;&nbsp;}&nbsp; <BR>}&nbsp; 
            <BR><BR>这个程序是父进程将参数写入到共享内存,然后子进程把内容读出来.最后我们要使用ipcrm释放资源的.先用ipcs找出ID然后用ipcrm&nbsp;shm&nbsp;ID删除.&nbsp; 
            <BR>后记:&nbsp; 
            <BR>进程通信(IPC)是网络程序的基础,在很多的网络程序当中会大量的使用进程通信的概念和知识.其实进程通信是一件非常复杂的事情,我在这里只是简单的介绍了一下.如果你想学习进程通信的详细知识,最好的办法是自己不断的写程序和看联机手册.现在网络上有了很多的知识可以去参考.可惜我看到的很多都是英文编写的.如果你找到了有中文的版本请尽快告诉我.谢谢!&nbsp; 
            <BR><BR><BR>&nbsp; <BR>&nbsp; <BR>(<A 
            href="http://www.fanqiang.com/">http://www.fanqiang.com/</A>) 
            </FONT>&nbsp;&nbsp;&nbsp;&nbsp;进入【<A 
            href="http://www.chinaunix.net/">UNIX论坛</A>】 </TD></TR>
        <TR>
          <TD>
            <HR>
          </TD></TR>
        <TR>
          <TD><B>相关文章</B> </TD></TR>
        <TR>
          <TD><A 
            href="http://www.fanqiang.com/a4/b2/20010508/113838.html">Linux下C语言编程--线程操作</A> 
            <SMALL>(2001-05-08 11:43:15)</SMALL></FONT><BR><A 
            href="http://www.fanqiang.com/a4/b2/20010508/113803.html">Linux下C语言编程--进程通信、消息管理</A> 
            <SMALL>(2001-05-08 11:38:03)</SMALL></FONT><BR><A 
            href="http://www.fanqiang.com/a4/b2/20010508/113528.html">Linux下C语言编程--信号处理函数</A> 
            <SMALL>(2001-05-08 11:35:28)</SMALL></FONT><BR><A 
            href="http://www.fanqiang.com/a4/b2/20010508/113412.html">Linux下C语言编程--时间概念</A> 
            <SMALL>(2001-05-08 11:34:12)</SMALL></FONT><BR><A 
            href="http://www.fanqiang.com/a4/b2/20010508/113315.html">Linux下C语言编程--文件的操作</A> 
            <SMALL>(2001-05-08 11:33:15)</SMALL></FONT><BR><A 
            href="http://www.fanqiang.com/a4/b2/20010508/113230.html">Linux下C语言编程--进程的创建</A> 
            <SMALL>(2001-05-08 11:32:30)</SMALL></FONT><BR><A 
            href="http://www.fanqiang.com/a4/b2/20010508/113129.html">Linux下C语言编程--基础知识</A> 
            <SMALL>(2001-05-08 11:31:29)</SMALL></FONT><BR></TD></TR>
        <TR>
        <TR>
          <TD></TD></TR>
        <TR>
          <TD>&nbsp;</TD></TR></TBODY></TABLE></TD></TR>
  <TR>
    <TD bgColor=#d09f0d colSpan=5 height=2 width="100%"><IMG height=1 
      src="[ 永远的UNIX  Linux下C语言编程--进程通信、消息管理 ].files/c.gif" width=1></TD></TR>
  <TR>
    <TD colSpan=5 height=40 vAlign=top width="100%">
      <P align=center><FONT color=#ffffff>★&nbsp;&nbsp;樊强制作 欢迎分享&nbsp;&nbsp;★ 
      </FONT></P></TD></TR></TBODY></TABLE></CENTER></DIV></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -