功能:
从队列中接收消息
参数:
msqid:已打开的消息队列id
msgp:存放消息的结构体指针。
msgsz:消息的字节数,指定mtext的大小。
msgtype:消息类型,消息类型 mtype的值。
msgflag:函数的控制属性。
msgflag:
MSG_NOERROR:若返回的消息比nbytes字节多,则消息就会截短到nbytes字节,且不通知消息发送进程.
IPC_NOWAIT:调用进程会立即返回.若没有收到消息则返回-1.
0:msgrcv调用阻塞直到条件满足为止.
在成功地读取了一条消息以后,队列中的这条消息将被删除。
例如:简单的消息收发
#include <sys/types.h> #include <sys/msg.h> #include <unistd.h> #include <string.h> #include <stdio.h> struct msg_buf { int mtype; char data[255]; }; int main( int argc, char *argv[] ) { key_t key; int msgid; int ret; struct msg_buf msgbuf; //get key key = fork( ".", "a" ); printf( "key = [%x]\n", key ); //create quee msgid = msgget( key, IPC_CREATE|0666 ); if( msgid = -1 ) { printf( "create err!\n" ); return -1; } //以当前进程类型,非阻塞方式发送"test data"到消息队列 msgbuf.mtype = getpid(); stpcpy( msgbuf.data, "test data" ); ret = msgsnd( msgid; &msgbuf, sizeof( msgbuf.data), IPC_NOWAIT ); if( ret == -1 ) { printf( "send err!\n" ); return -1; } //以非阻塞方式接收数据 memset ( &msgbuf, 0x00, sizeof( msgbuf) ); ret = msgrcv( msgid, &msgbuf, sizeof( msgbuf.data), getpid(), IPC_NOWAIT ); if( ret == -1 ) { printf( "rcv_err ret =[%d]!\n", ret ); return -1; } printf( "receive msg = [%s]\n!" , msgbuf.data ); return 0; } |
同一消息队列通信:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ipc.h> //要加这个头文件 struct msgbuf{ long mtype; char mtext[100]; }; //存放消息类型和消息内容的结构体 int main() { key_t key; int msgid; struct msgbuf msg1,msg2; //msg1用来发送,msg2用来接收 key=ftok(".", 0xf0); //获得消息队列标识符 if( (msgid = msgget(key, IPC_CREAT|0666)) < 0 ) //创建一个消息队列 { perror("msgget error"); exit(1); } msg1.mtype = 1; //消息类型为1,这个可以区别多个消息 memset(msg1.mtext, 0, 100); //将数组清0 strcpy(msg1.mtext, "hello"); //用strcpy给消息内容赋值 msgsnd(msgid, &msg1, strlen(msg1.mtext)+1, 0); //发送时最后加上一个‘\0’ printf("send %s\n", msg1.mtext); msgrcv(msgid, &msg2, 100, 1, 0); //接收1发过来的消息,存到msg2中 printf("receive %s\n", msg2.mtext); msgctl(msgid, IPC_RMID,NULL); //删除消息队列 return 0; } |
进程间消息队列通信:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ipc.h> #include <string.h> #include <signal.h> struct msgbuf{ int mtype; char mtext[100]; }; int main() { key_t key; pid_t pid; int msgid; struct msgbuf msg; key=ftok(".", 0x01); if ( (msgid = msgget(key, IPC_CREAT|0666)) <0 ) { perror("msgget error"); exit(1); } //创建一个进程 if ( (pid = fork()) < 0 ) { perror("fork error"); exit(1); } //子进程收信息 else if (pid==0) { while(1) { memset(msg.mtext,0,100); msgrcv(msgid,&msg,100,2,0); //receive the msg from 2 printf("\rbbb:%s\naaa:",msg.mtext); fflush(stdout); } exit(0); } //父进程发信息 else { while(1) { memset(msg.mtext,0,100); printf("aaa:"); fgets(msg.mtext,100,stdin); if (strncmp("bye",msg.mtext,3)==0)//如果前3个字符为bye,则退出 { kill(pid,SIGSTOP); exit(1); } msg.mtype=1;//send to 1 msg.mtext[strlen(msg.mtext)-1]='\0'; msgsnd(msgid,&msg,strlen(msg.mtext)+1,0); } } return 0; } |