进程通信之消息队列
2016-10-24 19:08
239 查看
消息队列就是一个消息的链表。可以把消息看做一个记录,具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向中按照一定的规则添加新信息,对消息队列有读权限的进程可以从消息队列中读走消息,消息队列是随内核持续的。
消息队列就是一个消息的链表。每个消息队列都有一个队列头,用结构struct msg_queue来描述。队列头中包含了该消息队列的大量信息,包括消息队列键值,用户ID,组ID,消息队列中消息数目等,甚至记录了最近对消息队列读写进程的ID。读者可以访问这些信息,也可以设置其中的某些信息。
全局数据结构struct ipc_ids msg_ids可以访问到每个消息队列头的第一个成员struct kern_ipc_perm能够与具体的消息队列对应起来是因为在该结构中,有一个key_t类型成员key,而key则确定一个消息队列。
消息队列的操作有以下三种类型。
1.打开或者创建消息队列
2.读写操作
3.获得或者设置消息队列属性。
消息队列的API函数
ftok函数:
作用:将文件名转化为键值
函数原型:key_t fotk(char *pathname ,char proj)
返回值:返回与文件对应的键值
2.msgget函数
作用:创建消息队列
原型:int msgget(key_t key,int msgflg)
参数:键值和权限,是可读还是可写,IPC_PRIVATE,设定一个数字,也可以由tok函数获得
返回值:成功则是消息队列的id,出错-1
包含的头文件:#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
3.msgsnd函数
作用:写数据到消息队列
原型:int msgsnd(int msgid,const void * msggp,size_t msgsize,int msgflg)
参数:msggp:消息结构
struct msgbuf{
long msgtype;
char mtext[1]
}
msgsize:消息的字节数
msgflg:IPC_NOWAIT写不进去消息直接返回
0一直等待到能写进去消息为止
返回值:成功为0
出错为-1;
包含的头文件:#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
4.msgrcv函数
作用:用于读出消息队列的数据
原型:int msgrcv(int msqid,struct msgbuf*msgp,int msgsz,long msgtyp,int msgflg)
返回值:成功返回读出消息的实际字节数,出错-1.
5.msgctl函数
作用:用于控制消息队列
原型:int msgctl(int msqid,int cmd,struct msqid_ds*buf);
该系统调用对由msqid标识的消息队列执行cmd操作,共有三种操作:IPC_STAT,IPC_SET,IPC_RMID
IPC_STAT:用来获取消息队列信息,返回的信息存储在buf指向的msqid结构中。
IPC_SET:用来设置消息队列的属性
IPC_RMID:删除msqd标识的消息队列
返回值:成功为0,否则返回-1。
每个消息队列的容量都有限制,该值因为系统不同而不同。另一个限制是每个消息队列所能容纳的最大消息数。
以下为应用实例
上面为读取的程序,开启一个中断,./read。
这是write的程序,在另外一个终端开启。
之后就可以实现在消息队列中读写。
消息队列就是一个消息的链表。每个消息队列都有一个队列头,用结构struct msg_queue来描述。队列头中包含了该消息队列的大量信息,包括消息队列键值,用户ID,组ID,消息队列中消息数目等,甚至记录了最近对消息队列读写进程的ID。读者可以访问这些信息,也可以设置其中的某些信息。
全局数据结构struct ipc_ids msg_ids可以访问到每个消息队列头的第一个成员struct kern_ipc_perm能够与具体的消息队列对应起来是因为在该结构中,有一个key_t类型成员key,而key则确定一个消息队列。
消息队列的操作有以下三种类型。
1.打开或者创建消息队列
2.读写操作
3.获得或者设置消息队列属性。
消息队列的API函数
ftok函数:
作用:将文件名转化为键值
函数原型:key_t fotk(char *pathname ,char proj)
返回值:返回与文件对应的键值
2.msgget函数
作用:创建消息队列
原型:int msgget(key_t key,int msgflg)
参数:键值和权限,是可读还是可写,IPC_PRIVATE,设定一个数字,也可以由tok函数获得
返回值:成功则是消息队列的id,出错-1
包含的头文件:#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
3.msgsnd函数
作用:写数据到消息队列
原型:int msgsnd(int msgid,const void * msggp,size_t msgsize,int msgflg)
参数:msggp:消息结构
struct msgbuf{
long msgtype;
char mtext[1]
}
msgsize:消息的字节数
msgflg:IPC_NOWAIT写不进去消息直接返回
0一直等待到能写进去消息为止
返回值:成功为0
出错为-1;
包含的头文件:#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
4.msgrcv函数
作用:用于读出消息队列的数据
原型:int msgrcv(int msqid,struct msgbuf*msgp,int msgsz,long msgtyp,int msgflg)
返回值:成功返回读出消息的实际字节数,出错-1.
5.msgctl函数
作用:用于控制消息队列
原型:int msgctl(int msqid,int cmd,struct msqid_ds*buf);
该系统调用对由msqid标识的消息队列执行cmd操作,共有三种操作:IPC_STAT,IPC_SET,IPC_RMID
IPC_STAT:用来获取消息队列信息,返回的信息存储在buf指向的msqid结构中。
IPC_SET:用来设置消息队列的属性
IPC_RMID:删除msqd标识的消息队列
返回值:成功为0,否则返回-1。
每个消息队列的容量都有限制,该值因为系统不同而不同。另一个限制是每个消息队列所能容纳的最大消息数。
以下为应用实例
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> struct my_msg_st { long int my_msg_type; char some_text[BUFSIZ]; }; int main(void) { int running=1; int msgid; struct my_msg_st some_data; long int msg_to_receive=0; /*创建消息队列*/ msgid=msgget((key_t)1234,0666 | IPC_CREAT); if(msgid==-1) { fprintf(stderr,"msgget failed with error: %d\n",errno); exit(EXIT_FAILURE); } /*循环从消息队列中接收消息*/ while(running) { /*读取消息*/ if(msgrcv(msgid,(void *)&some_data,BUFSIZ,msg_to_receive,0)==-1) { fprintf(stderr,"msgrcv failed with error: %d\n",errno); exit(EXIT_FAILURE); } printf("You wrote: %s",some_data.some_text); /*接收到的消息为“end”时结束循环*/ if(strncmp(some_data.some_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); }
上面为读取的程序,开启一个中断,./read。
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #define MAX_TEXT 512 struct my_msg_st { long int my_msg_type; char some_text[MAX_TEXT]; }; int main(void) { int running=1; struct my_msg_st some_data; int msgid; char buffer[BUFSIZ]; /*创建消息队列*/ msgid=msgget((key_t)1234,0666 | IPC_CREAT); if(msgid==-1) { fprintf(stderr,"msgget failed with error:%d\n",errno); exit(EXIT_FAILURE); } /*循环向消息队列中添加消息*/ while(running) { printf("Enter some text:"); fgets(buffer,BUFSIZ,stdin); some_data.my_msg_type=1; strcpy(some_data.some_text,buffer); /*添加消息*/ if(msgsnd(msgid,(void *)&some_data,MAX_TEXT,0)==-1) { fprintf(stderr,"msgsed failed\n"); exit(EXIT_FAILURE); } /*用户输入的为“end”时结束循环*/ if(strncmp(buffer,"end",3)==0) { running=0; } } exit(EXIT_SUCCESS); }
这是write的程序,在另外一个终端开启。
之后就可以实现在消息队列中读写。
相关文章推荐
- linux消息队列进程通信
- 进程间的通信--(四)消息队列
- linux进程通信--消息队列
- 进程通信-----消息队列
- Linux进程通信之POSIX消息队列
- linux进程通信---消息队列
- Linux进程通信IPC--消息队列MessageQueue
- [置顶] 【Linux】 进程通信--消息队列
- 多进程编程:Perl与C进程间的消息队列通信
- UNIX/LINUX编程学习之进程通信--消息队列
- linux消息队列进程通信
- php-通过共享内存实现消息队列和进程通信
- 父子进程通信的两种方式--消息队列和共享内存
- linux 进程间间通信使用消息队列
- 进程通信之消息队列
- Linux进程间的通信--消息队列
- Linux进程通信之消息队列
- linux消息队列进程通信
- wince进程通信----点对点消息队列
- linux c之通过消息队列实现进程通信