1消息队列
消息队列是一个消息链表,允许一个或多个进程向它写消息,另外的进程从中读取消息,具有FIFO的特性,但是可实现随即访问。在内核中,消息队列由"队列id"标识。
2.使用过程
创建消息队列==>添加消息==>读取消息==>删除队列
<1>创建消息队列 msgget()
int msgget(key_t key,int flag); 参数:key 为IPC_PRIVATE时,建立新的消息队列 不为IPC_PRIVATE,根据flag是否有IPC_CREAT确定 flag 标志位 返回:成功,返回消息队列识别代码msgid 失败 返回-1 错误信息存放在errno中 |
<2>向消息队列添加消息
int msgsnd(int msgid,struct msgbuf *msgp,size_t msgsz,int flag); 参数:msgid 消息队列id 由msgget()得到 msgp 存放消息类型和内容
msgbuf在头文件中未实际定义,需要自己定义。 msgsz 消息大小 flag 为IPC_NOWAIT时,未立即发送,调用进程立即返回 返回:成功,返回消息队列识别代码 失败 返回-1 错误信息存放在errno中 |
<3>从消息队列读取消息
int msgrcv(int msgid,struct msgbuf *msgp,size_t msgsz,long msgty,int flag);
参数: msgid 消息队列id 由msgget()得到 msgp 存放消息类型和内容 msgsz 消息大小 msgty 消息类型 flag 为IPC_NOWAIT时,未立即发送,调用进程立即返回 返回:成功,返回消息队列识别代码 失败 返回-1 错误信息存放在errno中
|
<4>控制消息队列
int msgctl(int msgid,int cmd,struct msgid_ds, *buf); 参数: msgid 消息队列id 由msgget()得到 cmd IPC_STAT 将消息队列信息写入buf IPC_SET 根据buf设置为消息队列 IPC_RMID 删除消息队列 返回:成功,返回消息队列识别代码 失败 返回-1 错误信息存放在errno中 |
举例:
1. 子进程向消息队列发送消息,由父进程读出
- #include<sys/ipc.h>
- #include<sys/msg.h>
- #include<sys/types.h>
- #include<sys/stat.h>
- #include<unistd.h>
- #include<stdio.h>
- #include<string.h>
- #define KEY 1234
- #define MSGTYPE 4321
- #define SIZE 512
- int main()
- {
- int msgid;/*消息队列id*/
- pid_t pid;
- struct message
- {
- long mtype;
- char mtext[SIZE];
- }msg;
- msgid=msgget(KEY,IPC_CREAT);
- pid=fork();
- if(pid<0)
- {
- perror("fork error!\n");
- exit(0);
- }
- if(pid==0)
- {
- /*子进程发送消息*/
- msg.mtype=MSGTYPE;/*设置消息类型*/
- sprintf(msg.mtext,"hello linux!");/*设置消息内容*/
- msgsnd(msgid,&msg,SIZE,IPC_NOWAIT);/*发送消息*/
- printf("son proc send msg!\n");
- exit(0);
- }
- /*父进程接收消息*/
- sleep(2);
- msgrcv(msgid,&msg,SIZE,MSGTYPE,MSG_NOERROR|IPC_NOWAIT);/*接收消息*/
- printf("parent get message:%s\n",msg.mtext,IPC_NOWAIT);
- msgctl(msgid,IPC_RMID,NULL);/*删除消息队列*/
- }