如何知道进程在一个空消息队列中放入一个消息?如果阻塞在msgrcv调用中,则除了等待无法做其他事情,如果给msgrcv指定非阻塞标志(IPC_NOWAIT),尽管不阻塞了,但必须持续调用该函数来确定何时有消息到达,也就是采用轮询方式(polling),Posix消息队列允许异步事件通知来通知何时有消息放入到某个空消息队列中,有2种方式:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
1)产生一个信号
2)创建一个线程执行一个指定函数
这通过mq_notify建立。
unionsigval
{
intsival_int;
void*sival_ptr;
};
structsigevent
{
intsigev_notify;
intsigev_signo;
unionsigvalsigev_value;
void(*sigev_notify_function)(unionsigval);
pthread_attr_t*sigev_notify_attributes;
};
#include"unpipc.h"
volatilesig_atomic_tmqflag;
staticvoidsig_usr1(intsigno)
{
mqflag=1;
return;
}
intmain(intargc,char**argv)
{
mqd_tmqd;
void*buff;
SSIZE_Tn;
sigset_tzeromask,newmask,oldmask;
structmq_attrattr;
structsigeventsigev;
mqd=mq_open(argv[1],O_RDONLY|O_NONBLOCK);//打开消息队列
mq_getattr(mqd,&attr);
buff=malloc(attr.mq_msgsize);//创建接收缓冲区
sigemptyset(&zeromask);
sigemptyset(&newmask);
sigemptyset(&oldmask);
sigaddset(&newmask,SIGUSR1);
//初始化信号处理
signal(SIGUSR1,sig_usr1);
sigev.sigev_notify=SIGEV_SIGNAL;
sigev.sigev_signo=SIGUSR1;
mq_notify(mqd,&sigev);
for(;;)
{
sigprocmask(SIG_BLOCK,&newmask,&oldmask);//阻塞SIGUSR1信号
while(mqflag==0)sigsuspend(&zeromask);
mqflag=0;
mq_notify(mqd,&sigev);
while((n=mq_receive(mqd,buff,attr.mq_msgsize,NULL))>=0)
{//循环接收数据
printf("read%ldbytes/n",(long)n);
}
sigprocmask(SIG_UNBLOCK,&newmask,NULL);
}
exit(0);
}
structmsqid_ds
{
structipc_permmsg_perm;
structmsg*msg_first;
structmsg*msg_last;
msgle_tmsg_cbytes;
msgqnum_tmsg_qnum;
msglen_tmsg_qbytes;
pid_tmsg_lspid;
pid_tmsg_lrpid;
time_tmsg_stime;
time_tmsg_rtime;
time_tmsg_ctime;
};
msgget创建一个新的消息队列或访问一个已经存在的消息队列
msgsnd发送一个消息,消息是下面这样的结构体:
structmsgbuf
{
longmtype;//消息类型
charmtext[1];//消息数据
};
但这个预定的结构一般无法满足自己的需求,因此一般定义自己的结构
typedefstructmy_msgbuf
{
longmtype;
int16_tmshort;//消息数据起始
charmchar[MY_DATA];
}Message;
发送数据时可以指定flag为IPC_NOWAIT,这个标志使得msgsnd调用非阻塞,
调用msgrcv函数时,若type指定为0,则返回消息队列第一个消息,若type小于0,则返回类型值小于或等于type绝对值的消息中类型值最小的
第一个消息
使用两个消息队列来实现前面的客户—服务器例子,一个队列用于从客户方到服务器的消息,一个队列用于从服务器到客户的消息。
#include"unpipc.h"
#defineMQ_KEY11234L
#defineMQ_KEY22345L
intmain()
{
intreadid,writeid;
readid=msgget(MQ_KEY1,SVMSG_MODE|IPC_CREATE);
writeid=msgget(MQ_KEY2,SVMSG_MODE|IPC_CREATE);
server(readid,writeid);
exit(0);
}
intmain()
{
intreadid,writeid;
readid=msgget(MQ_KEY2,0);
writeid=msgget(MQ_KEY1,0);
client(readid,writeid);
//删除消息队列
msgctl(readid,IPC_RMID,NULL)
msgctl(writeid,IPC_RMID,NULL);
exit(0);
}
第8节使用一个队列来实现单服务器,多客户端的通信,但互斥,死锁可能存在,另一种思路就是为每个实体单独设置一个私有队列,消息都发送到自己的队列中,也只从自己的队列中取消息.
System V的消息队列比Posix消息队列差多了,要使用select模型同时处理网络连接和IPC连接时,必须产生子进程,使用管道作为中介,另外一个弱点是无法Peek一个消息.
分享到:
相关推荐
unix网络编程卷2第二版英文版 unix网络编程卷2第二版英文版 unix网络编程卷2第二版英文版 unix网络编程卷2第二版英文版 unix网络编程卷2第二版英文版 unix网络编程卷2第二版英文版 unix网络编程卷2第二版英文版 unix...
《LINUX与UNIX SHELL编程指南》读书笔记-二次发布版
笔记_UNIX环境网络编程卷二进程间通信_中文第二版
UNIX网络编程卷1代码.rarUNIX网络编程卷1代码.rar
《UNIX网络编程》(第1卷)(套接口API第3版)第1版和第2版由已故UNIX网络专家W. Richard Stevens博士独自编写。《UNIX网络编程》(第1卷)(套接口API第3版)是3版,由世界著名网络专家Bill Fenner和Andrew M. Rudoff执笔,...
UNIX网络编程随书源代码(包含卷一卷二)
unix网络编程第2版(1 2卷).pdf UNIX网络编程卷1:套接字联网API(第3版).pdf UNIX网络编程 卷2:进程间通信(第2版).pdf 计算机网络(第七版)复习题答案与课本对应.doc 计算机网络(第7版)-谢希仁.pdf
卷2:进程间通信(第2版)》是一部UNIX网络编程的经典之作!进程间通信(IPC)几乎是所有Unix程序性能的关键,理解IPC也是理解如何开发不同主机间网络应用程序的必要条件。《UNIX网络编程.卷2:进程间通信(第2版)》从对...
unix网络编程卷2,介绍的内容很全面,很适合刚接触linux或者unix网络编程开发人员学习
UNIX网络编程 卷2
UNIX环境高级编程高清版_PDF版 + UNIX网络编程卷1高清版_PDF版
unix网络编程-第三版读书笔记unix网络编程-第三版读书笔记
unix网络编程读书笔记unix网络编程读书笔记unix网络编程读书笔记unix网络编程读书笔记unix网络编程读书笔记
UNIX 网络编程卷 2 进程间通信读书笔记(一)
《UNIX网络编程 卷1:套接字联网API(第2版)》是一部UNIX网络编程的经典之作。书中全面深入地介绍了如何使用套接字API进行网络编程。全书不但介绍了基本编程内容,还涵盖了与套接字编程相关的高级主题,对于客户/...
( UNIX网络编程 卷2:进程间通信(第2版)中文PDF版,网络编程基础
UNIX网络编程卷1(第三版 英文版).pdf
改资源是zip压缩包,里面包括: UNIX网络编程(第2版)卷1:套接口API和XOpen.传输接口API.pdf UNIX网络编程(第2版)卷2:进程间通信.pdf
UNIX网络编程 卷2:进程间通信(第2版)PDF 及 源代码; PDF 是中文扫描版的; 源代码里面有 .tar.gz 【在MAC/Linux/Unix 环境下使用 “tar zxvf xxx.tar.gz”解压】 以及 .zip 两种格式的文件【它们内容是一样的】...