﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-sopherwenxin学习笔记-文章分类-Linux</title><link>http://www.cppblog.com/sopherwenxin/category/782.html</link><description>刀锋上的舞者: 我是风中的落叶，看我如何飞翔</description><language>zh-cn</language><lastBuildDate>Mon, 19 May 2008 14:36:50 GMT</lastBuildDate><pubDate>Mon, 19 May 2008 14:36:50 GMT</pubDate><ttl>60</ttl><item><title>SystemV消息队列</title><link>http://www.cppblog.com/sopherwenxin/articles/2596.html</link><dc:creator>sopherwenxin</dc:creator><author>sopherwenxin</author><pubDate>Wed, 11 Jan 2006 12:50:00 GMT</pubDate><guid>http://www.cppblog.com/sopherwenxin/articles/2596.html</guid><wfw:comment>http://www.cppblog.com/sopherwenxin/comments/2596.html</wfw:comment><comments>http://www.cppblog.com/sopherwenxin/articles/2596.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sopherwenxin/comments/commentRss/2596.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sopherwenxin/services/trackbacks/2596.html</trackback:ping><description><![CDATA[<P>SystemV消息队列 为了便于进程之间通信,我们可以使用管道通信 SystemV也提供了一些函数来实现进程的通信.这就是消息队列. </P>
<P>#include <BR>#include <BR>#include </P>
<P>int msgget(key_t key,int msgflg); <BR>int msgsnd(int msgid,struct msgbuf *msgp,int msgsz,int msgflg); <BR>int msgrcv(int msgid,struct msgbuf *msgp,int msgsz, <BR>long msgtype,int msgflg); <BR>int msgctl(Int msgid,int cmd,struct msqid_ds *buf); </P>
<P>struct msgbuf { <BR>long msgtype; /* 消息类型 */ <BR>……. /* 其他数据类型 */ <BR>} </P>
<P>msgget函数和semget一样,返回一个消息队列的标志.msgctl和semctl是对消息进行控制. msgsnd和msgrcv函数是用来进行消息通讯的.msgid是接受或者发送的消息队列标志. msgp是接受或者发送的内容.msgsz是消息的大小. 结构msgbuf包含的内容是至少有一个为msgtype.其他的成分是用户定义的.对于发送函数msgflg指出缓冲区用完时候的操作.接受函数指出无消息时候的处理.一般为0. 接收函数msgtype指出接收消息时候的操作. <BR>如果msgtype=0,接收消息队列的第一个消息.大于0接收队列中消息类型等于这个值的第一个消息.小于0接收消息队列中小于或者等于msgtype绝对值的所有消息中的最小一个消息. 我们以一个实例来解释进程通信.下面这个程序有server和client组成.先运行服务端后运行客户端. <BR>服务端 server.c </P>
<P>#include <BR>#include <BR>#include <BR>#include <BR>#include <BR>#include <BR>#include <BR>#include <BR>#include </P>
<P>#define MSG_FILE “server.c” <BR>#define BUFFER 255 <BR>#define PERM S_IRUSR|S_IWUSR </P>
<P>struct msgtype { <BR>long mtype; <BR>char buffer[BUFFER+1]; <BR>}; </P>
<P>int main() <BR>{ <BR>struct msgtype msg; <BR>key_t key; <BR>int msgid; </P>
<P>if((key=ftok(MSG_FILE,’a'))==-1) <BR>{ <BR>fprintf(stderr,”Creat Key Error:%s\a\n”,strerror(errno)); <BR>exit(1); <BR>} </P>
<P>if((msgid=msgget(key,PERM|IPC_CREAT|IPC_EXCL))==-1) <BR>{ <BR>fprintf(stderr,”Creat Message Error:%s\a\n”,strerror(errno)); <BR>exit(1); <BR>} </P>
<P>while(1) <BR>{ <BR>msgrcv(msgid,&amp;msg,sizeof(struct msgtype),1,0); <BR>fprintf(stderr,”Server Receive:%s\n”,msg.buffer); <BR>msg.mtype=2; <BR>msgsnd(msgid,&amp;msg,sizeof(struct msgtype),0); <BR>} <BR>exit(0); <BR>} </P>
<P>——————————————————————————– </P>
<P>客户端(client.c) </P>
<P>#include <BR>#include <BR>#include <BR>#include <BR>#include <BR>#include <BR>#include <BR>#include <BR>#define MSG_FILE “server.c” <BR>#define BUFFER 255 <BR>#define PERM S_IRUSR|S_IWUSR </P>
<P>struct msgtype { <BR>long mtype; <BR>char buffer[BUFFER+1]; <BR>}; </P>
<P>int main(int argc,char **argv) <BR>{ <BR>struct msgtype msg; <BR>key_t key; <BR>int msgid; </P>
<P>if(argc!=2) <BR>{ <BR>fprintf(stderr,”Usage:%s string\n\a”,argv[0]); <BR>exit(1); <BR>} </P>
<P>if((key=ftok(MSG_FILE,’a'))==-1) <BR>{ <BR>fprintf(stderr,”Creat Key Error:%s\a\n”,strerror(errno)); <BR>exit(1); <BR>} </P>
<P>if((msgid=msgget(key,PERM))==-1) <BR>{ <BR>fprintf(stderr,”Creat Message Error:%s\a\n”,strerror(errno)); <BR>exit(1); <BR>} </P>
<P>msg.mtype=1; <BR>strncpy(msg.buffer,argv[1],BUFFER); <BR>msgsnd(msgid,&amp;msg,sizeof(struct msgtype),0); <BR>memset(&amp;msg,’\0′,sizeof(struct msgtype)); <BR>msgrcv(msgid,&amp;msg,sizeof(struct msgtype),2,0); <BR>fprintf(stderr,”Client receive:%s\n”,msg.buffer); <BR>exit(0); <BR>} </P>
<P>注意服务端创建的消息队列最后没有删除,我们要使用ipcrm命令来删除的. </P><img src ="http://www.cppblog.com/sopherwenxin/aggbug/2596.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sopherwenxin/" target="_blank">sopherwenxin</a> 2006-01-11 20:50 <a href="http://www.cppblog.com/sopherwenxin/articles/2596.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>