博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
练习--LINUX进程间通信之消息队列MSG
阅读量:5112 次
发布时间:2019-06-13

本文共 3362 字,大约阅读时间需要 11 分钟。

https://www.ibm.com/developerworks/cn/linux/l-ipc/part3/

继续坚持,或许不能深刻理解,但至少要保证有印象。

~~~~~~~~~~~~~~

消息队列(也叫做报文队列)能够克服早期unix通信机制的一些缺点。作为早期unix通信机制之一的信号能够传送的信息量有限,后来虽然POSIX 1003.1b在信号的实时性方面作了拓广,使得信号在传递信息量方面有了相当程度的改进,但是信号这种通信方式更像"即时"的通信方式,它要求接受信号的进程在某个时间范围内对信号做出反应,因此该信号最多在接受信号进程的生命周期内才有意义,信号所传递的信息是接近于随进程持续的概念(process-persistent),见 ;管道及有名管道及有名管道则是典型的随进程持续IPC,并且,只能传送无格式的字节流无疑会给应用程序开发带来不便,另外,它的缓冲区大小也受到限制。

消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向中按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读走消息。消息队列是随内核持续的(参见 )。

目前主要有两种类型的消息队列:POSIX消息队列以及系统V消息队列,系统V消息队列目前被大量使用。考虑到程序的可移植性,新开发的应用程序应尽量使用POSIX消息队列。

在本系列专题的序(深刻理解Linux进程间通信(IPC))中,提到对于消息队列、信号灯、以及共享内存区来说,有两个实现版本:POSIX的以及系统V的。Linux内核(内核2.4.18)支持POSIX信号灯、POSIX共享内存区以及POSIX消息队列,但对于主流Linux发行版本之一redhad8.0(内核2.4.18),还没有提供对POSIX进程间通信API的支持,不过应该只是时间上的事。

~~~~~~~~~~~~~~~

/***************** * * test.c* *******************/#include 
#include
#include
#include
#include
void msg_stat(int, struct msqid_ds);main(){ int gflags, sflags, rflags; key_t key; int msgid; int reval; struct msgsbuf{ int mtype; char mtext[1]; }msg_sbuf; struct msgmbuf{ int mtype; char mtext[10]; }msg_rbuf; struct msqid_ds msg_ginfo, msg_sinfo; char* msgpath = "/tmp/msgqueue"; key=ftok(msgpath, 'a'); gflags = IPC_CREAT|IPC_EXCL; msgid = msgget(key, gflags|00666); if(msgid == -1) { printf("msg create error\n"); return; } msg_stat(msgid, msg_ginfo); sflags=IPC_NOWAIT; msg_sbuf.mtype = 10; msg_sbuf.mtext[0] = 'a'; reval = msgsnd(msgid, &msg_sbuf, sizeof(msg_sbuf), sflags); if(reval == -1) { printf("message send error\n"); } msg_stat(msgid, msg_ginfo); rflags = IPC_NOWAIT|MSG_NOERROR; reval = msgrcv(msgid, &msg_rbuf, 4, 10, rflags); if(reval == -1) printf("read msg error\n"); else printf("read from msg queue %d bytes\n", reval); msg_stat(msgid, msg_ginfo); msg_sinfo.msg_perm.uid = 8; msg_sinfo.msg_perm.gid = 8; msg_sinfo.msg_qbytes = 16388; reval = msgctl(msgid, IPC_SET, &msg_sinfo); if(reval == -1) { printf("msg set info error\n"); return; } msg_stat(msgid, msg_ginfo); reval = msgctl(msgid, IPC_RMID, NULL); if(reval == -1) { printf("unlink msg queue error\n"); return; }}void msg_stat(int msgid, struct msqid_ds msg_info){ int reval; sleep(1); reval = msgctl(msgid, IPC_STAT, &msg_info); if(reval == -1) { printf("get msg info error\n"); return; } printf("\n"); printf("current number of bytes on queue is %d\n", msg_info.msg_cbytes); printf("number of messages in queue is %d\n",msg_info.msg_qnum); printf("max number of bytes on queue is %d\n",msg_info.msg_qbytes); printf("pid of last msgsnd is %d\n",msg_info.msg_lspid); printf("pid of last msgrcv is %d\n",msg_info.msg_lrpid); printf("last msgsnd time is %s", ctime(&(msg_info.msg_stime))); printf("last msgrcv time is %s", ctime(&(msg_info.msg_rtime))); printf("last change time is %s", ctime(&(msg_info.msg_ctime))); printf("msg uid is %d\n",msg_info.msg_perm.uid); printf("msg gid is %d\n",msg_info.msg_perm.gid);}

 

转载于:https://www.cnblogs.com/aguncn/p/4985390.html

你可能感兴趣的文章
《绿色·精简·性感·迷你版》易语言,小到不可想象
查看>>
Android打包key密码丢失找回
查看>>
VC6.0调试技巧(一)(转)
查看>>
类库与框架,强类型与弱类型的闲聊
查看>>
webView添加头视图
查看>>
php match_model的简单使用
查看>>
在NT中直接访问物理内存
查看>>
Intel HEX 文件格式
查看>>
SIP服务器性能测试工具SIPp使用指导(转)
查看>>
php_扑克类
查看>>
回调没用,加上iframe提交表单
查看>>
(安卓)一般安卓开始界面 Loding 跳转 实例 ---亲测!
查看>>
Mysql 索引优化 - 1
查看>>
LeetCode(3) || Median of Two Sorted Arrays
查看>>
大话文本检测经典模型:EAST
查看>>
待整理
查看>>
一次动态sql查询订单数据的设计
查看>>
C# 类(10) 抽象类.
查看>>
Vue_(组件通讯)子组件向父组件传值
查看>>
jvm参数
查看>>