Linux下多进程编程消息队列
一、消息队列
一个或多个进程可向消息队列写入消息;
一个或其他多个进行可从消息队列中读取消息。
linux中的消息被描述成是内核地址空间中的一个内部链表;
每个消息队列有一个IPC(inter-Process Communication 进程间通信)的标识号唯一的标识
linux为系统中的所有消息队列维护一个msgque链表,每个消息队列都在系统范围内对应唯一的键值,想获得一个消息队列描述字,只需要提供该消息队列的键值。
消息队列的原型是结构体,定义在linux/msg.h
struct msgbuf { __kernel_long_t mtype; /* type of message */ char mtext[1]; /* message text */ };
结构将不同类型的数据组合成一个整体,mtype标识消息类型;mtext标识消息内容。
虽然在mtext是大小为1的字符数组,应用中消息长度可以是任意的,定制可以通过malloc中的长度改变实现。linux下在为结构体变量分配内存是,常将最后一个成员长度设置为1,在动态申请内存时可以申请不同大小的缓冲区,并且大小不受结构变量长度的显示。
二、消息队列相关函数:
1、msgget(),获取与某个键值相关联的消息队列标识
2、msgsnd(),将新消息写入队列
3、msgrcv(),从消息队列中读取消息
4、msgctl(),根据命令控制消息的操作
三、发送代码:test7_10.c
1 /* *=+=+=+=+* *** *=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= 2 * 作者代号: *** :guochaoxxl 3 * 版权声明: *** :(魎魍魅魑)GPL3 4 * 联络信箱: *** :guochaoxxl@163.com 5 * 文档用途: *** :深入理解C指针 6 * 文档信息: *** :~/test7_10.c 7 * 修订时间: *** :2020年第46周 11月20日 星期五 上午09:11 (325天) 8 * 代码说明: *** :自行添加 9 * *+=+=+=+=* *** *+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+*/ 10 #define _GNU_SOURCE 11 #include <stdio.h> 12 #include <sys/ipc.h> 13 #include <sys/msg.h> 14 #include <sys/types.h> 15 #define QUE_ID 2 16 17 //使用公共消息队列,读写进程可以不同时运行。 18 int main(int argc, char **argv) 19 { 20 int queue_id; 21 struct msgbuf *msg; 22 int rc; 23 24 //建立消息队列 25 queue_id=msgget(QUE_ID,IPC_CREAT|0600);//QUE_ID为一个正整数,公共消息队的ID 26 if (queue_id==-1){ 27 perror("create queue error!\n"); 28 exit(1); 29 } 30 31 printf("message %d queue created!\n",queue_id); 32 //创建发送消息结构 33 printf("message send....\n"); 34 35 msg=(struct msgbuf*)malloc(sizeof(struct msgbuf)+100);//100为消息的长度,msgbuf构只有2个成员一个成员是mytpe,另一个成员是一个字节的mtext,在结构后分配更多的间以存放消> 息字符串 36 msg->mtype=1;//消息类型,正整数 37 strcpy(msg->mtext,"hello,world"); 38 //发送消息 39 rc=msgsnd(queue_id,msg,100,0); 40 //最后一个参数可以是是0与随后这些值(或者就是0):IPC_NOWAIT,如果消息类型有则立即返回,函数调用失败 41 //MSG_EXCEPT,当消息类型大于0时,读与消息类型不同的第一条消息 42 //MSG_NOERROR,如果消息长度大于100字节则被截掉 43 if (rc==-1){ 44 perror("msgsnd error\n"); 45 exit(1); 46 } 47 48 free(msg);//发送完毕,释放内存 49 printf("message sended!\n"); 50 51 return 0; 52 }
接受代码:test7_11.c
1 /* *=+=+=+=+* *** *=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= 2 * 作者代号: *** :guochaoxxl 3 * 版权声明: *** :(魎魍魅魑)GPL3 4 * 联络信箱: *** :guochaoxxl@163.com 5 * 文档用途: *** :深入理解C指针 6 * 文档信息: *** :~/test7_11.c 7 * 修订时间: *** :2020年第46周 11月20日 星期五 上午09:14 (325天) 8 * 代码说明: *** :自行添加 9 * *+=+=+=+=* *** *+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+*/ 10 #define _GNU_SOURCE 11 #include <stdio.h> 12 #include <sys/ipc.h> 13 #include <sys/msg.h> 14 #include <sys/types.h> 15 #define QUE_ID 2 16 17 //使用公共消息队列,读写进程可以不同时运行。 18 int main(int argc, char **argv) 19 { 20 int queue_id; 21 struct msgbuf *msg; 22 int rc; 23 24 //取得消息队列 25 queue_id=msgget(QUE_ID,0);//QUE_ID为一个正整数,公共消息队列的ID, 26 27 if (queue_id==-1){ 28 perror("get queue error!\n"); 29 exit(1); 30 } 31 32 printf("message recv....\n"); 33 msg=(struct msgbuf*)malloc(sizeof(struct msgbuf)+100); 34 rc=msgrcv(queue_id,msg,101,0,0); 35 if (rc==-1){ 36 perror("recv error\n"); 37 exit(1); 38 } 39 printf("recv:%s\n",msg->mtext); 40 41 return 0; 42 }
结果为:
发送: 请按 ENTER 或其它命令继续 message 0 queue created! message send.... message sended! 接受: message recv.... recv:hello,world
人就像是被蒙着眼推磨的驴子,生活就像一条鞭子;当鞭子抽到你背上时,你就只能一直往前走,虽然连你也不知道要走到什么时候为止,便一直这么坚持着。