进程间的通信--(四)消息队列
来源:互联网 发布:查找excel两表相同数据 编辑:程序博客网 时间:2024/06/11 23:14
消息队列
一、什么是消息队列
消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法。 每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构。我们可以通过发送消息来避免命名管道的同步和阻塞问题。但是消息队列与命名管道一样,每个数据块都有一个最大长度的限制。
Linux用宏MSGMAX和MSGMNB来限制一条消息的最大长度和一个队列的最大长度。
二、在Linux中使用消息队列
1、用msgget()
函数创建和访问消息队列:
int msgget(key_t key,int msgflg);
msgflg是一个权限标志,表示消息队列的访问权限,它与文件的访问权限一样。msgflg可以与IPC_CREAT做或操作,表示当key所命名的消息队列不存在时创建一个消息队列,如果key所命名的消息队列存在时,IPC_CREAT标志会被忽略,而只返回一个标识符。
2、msgsnd()函数
把消息添加到消息队列中:
int msgsnd(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg)
msgid是由msgget函数返回的消息队列标识符。
msg_ptr是一个指向准备发送消息的指针,但是消息的数据结构却有一定的要求,指针msg_ptr所指向的消息结构一定要是以一个长整型成员变量开始的结构体,接收函数将用这个成员来确定消息的类型。所以消息结构要定义成这样:
它返回一个以key命名的消息队列的标识符(非零整数),失败时返回-1.
int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg);
struct msqid_ds{
uid_t msg_perm.uid;
uid_t msg_perm.gid;
uid_t msg_perm.mode;
}
第一个参数是队列标识符,第二个参数是即将要采取的动作
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <sys/msg.h> struct msg_st { long int msg_type; char text[BUFSIZ]; }; int main() { int running = 1; int msgid = -1; struct msg_st data; long int msgtype = 0; //注意1 //建立消息队列 msgid = msgget((key_t)1234, 0666 | IPC_CREAT); if(msgid == -1) { fprintf(stderr, "msgget failed with error: %d\n", errno); exit(EXIT_FAILURE); } //从队列中获取消息,直到遇到end消息为止 while(running) { if(msgrcv(msgid, (void*)&data, BUFSIZ, msgtype, 0) == -1) { fprintf(stderr, "msgrcv failed with errno: %d\n", errno); exit(EXIT_FAILURE); } printf("You wrote: %s\n",data.text); //遇到end结束 if(strncmp(data.text, "end", 3) == 0) running = 0; } //删除消息队列 if(msgctl(msgid, IPC_RMID, 0) == -1) { fprintf(stderr, "msgctl(IPC_RMID) failed\n"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <sys/msg.h> #include <errno.h> #define MAX_TEXT 512 struct msg_st { long int msg_type; char text[MAX_TEXT]; }; int main() { int running = 1; struct msg_st data; char buffer[BUFSIZ]; int msgid = -1; //建立消息队列 msgid = msgget((key_t)1234, 0666 | IPC_CREAT); if(msgid == -1) { fprintf(stderr, "msgget failed with error: %d\n", errno); exit(EXIT_FAILURE); } //向消息队列中写消息,直到写入end while(running) { //输入数据 printf("Enter some text: "); fgets(buffer, BUFSIZ, stdin); data.msg_type = 1; //注意2 strcpy(data.text, buffer); //向队列发送数据 if(msgsnd(msgid, (void*)&data, MAX_TEXT, 0) == -1) { fprintf(stderr, "msgsnd failed\n"); exit(EXIT_FAILURE); } //输入end结束输入 if(strncmp(buffer, "end", 3) == 0) running = 0; sleep(1); } exit(EXIT_SUCCESS); }
- 进程间通信(四)------消息队列
- 进程间的通信--(四)消息队列
- 进程间通信简介(四)——消息队列
- 四.Linux环境进程间通信(三):消息队列:系统V消息队列
- 四.Linux环境进程间通信(三):消息队列:POSIX 消息队列
- Linux进程间通信(简单的消息队列通信)
- 进程间的通信之消息队列
- 进程间的通信-消息队列
- linux进程间的通信: 消息队列
- Linux的进程间通信-消息队列
- Linux的进程间通信-消息队列
- Linux进程间的通信--消息队列
- 进程间的通信之消息队列
- 进程间的通信---消息队列
- 进程间通信学习笔记四(消息队列)
- Linux进程通信总结(四) --消息队列
- 进程间通信(消息队列)
- 进程间通信(三):消息队列
- 原串翻转
- C++中virtual相关的知识
- 面试题3:数组中重复的数字
- Python进阶之MySQL数据库在linux中中文的插入和显示问题
- angularjs实现
- 进程间的通信--(四)消息队列
- 后缀表达式
- Java基础练习-输入的年份、产品类型和随机数产生固定资产编号
- 视觉slam14讲——习题部分
- hdu 4416 后缀自动机 问在S中有多少个不同子串满足它不是s1~sn中任意一个字符串的子串
- 洛谷 p1970
- 远程调用webservice接口的实现方法
- 第五周 项目1
- ccf 201703-3 Markdown