优缺点
- 消息队列只适用于单台主机的进程间通信,如果是不同主机,需要用socket等其他方式,也就不属于IPC的范畴了。
- 消息队列可以实现异步通信,这似乎是优点,但说是它缺点也是可以的:通讯往往不是实时的。
- 消息队列有大小限制,通常只用于小数据量的发送。系统对用户的大小限制可以通过 ulimit -q 命令进行查询。
- 消息队列可以实现阻塞调用和非阻塞调用。
- 实现简单,且可移植性好。
演示
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/msg.h>
- int main(int argc, char *argv[]){
- int ipc_key,msg_id,msg_len;
- long mtype;
- void * mbuf;
- if(argc==5 && argv[3][0]=='s'){
- ipc_key=atoi(argv[1]);
- mtype=atol(argv[2]);
- msg_len=strlen(argv[4]);
- if ( 0>(msg_id=msgget(ipc_key, 0666|IPC_CREAT)))return 1;
- if ( NULL==(mbuf=malloc(msg_len+sizeof(long)+1)) )return 2;
- memcpy(mbuf, (void *)&mtype, sizeof(long) );
- memcpy(mbuf+sizeof(long), (void *)argv[4], msg_len );
- if ( 0>msgsnd(msg_id, (struct msgbuf *)mbuf, msg_len, 0) )return 3;
- printf("Send Success.n");
- }else if(argc==4 && argv[3][0]=='r'){
- ipc_key=atoi(argv[1]);
- mtype=atol(argv[2]);
- if ( 0>(msg_id=msgget(ipc_key, 0666)))return 1;
- if ( NULL==(mbuf=malloc(4096)) )return 2;
- if ( 0>(msg_len=msgrcv(msg_id,(struct msgbuf *)mbuf, 4000, mtype, IPC_NOWAIT))){
- printf("No message received.n");
- return 3;
- }
- printf("Recv Success.(%d bytes):n",msg_len);
- printf("%sn",(char *)(mbuf+sizeof(long)));
- }else if(argc==3 && argv[2][0]=='c'){
- ipc_key=atoi(argv[1]);
- if ( 0>(msg_id=msgget(ipc_key, 0666)))return 1;
- if ( 0>msgctl(msg_id,IPC_RMID,(struct msqid_ds *)mbuf) )return 2;
- }else{
- printf("usage:"
- "%s key type s message --to send messagen"
- "%s key type r --to receiven"
- "%s key c --to clear queuen"
- ,argv[0],argv[0],argv[0]);
- }
- return 0;
- }
以上程序,实现了发数据到消息队列和从消息队列收取数据的功能。
第一个参数需要是一个整形数值,表示消息队列的Key;
第二个参数是一个长整形的数值,表示消息的Type,Key+Type 可以唯一确定一个先进先出的消息队列。
第三个参数如果是‘s’则把第四个参数发到指定消息队列,如果是‘r’则从指定消息队列收取消息,并打印。
另外,如果第二个函数是‘c’,则把Key对应的队列删除。
$ gcc -o ipc_msg ipc_msg.c $ ipcs -q
Message Queues --------
key msqid owner perms used-bytes messages
一开始队列里没有消息。
$ ./ipc_msg 1 2 s abc Send Success. $ ipcs -q
Message Queues --------
key msqid owner perms used-bytes messages 0x00000001 262144 lily 666 3 1
发送了一个消息以后,队列里有消息了,key是1,有3个字节。
$ ./ipc_msg 1 2 r Recv Success.(3 bytes): abc
从消息队列成功收到消息了。
$ ipcs -q
Message Queues --------
key msqid owner perms used-bytes messages 0x00000001 262144 lily 666 0 0
收完以后,空的消息队列仍然存在,不会自动消失。
$ ./ipc_msg 1 c
删除队列
$ ipcs -q
Message Queues --------
key msqid owner perms used-bytes messages
成功删除了,回到原始状态。