Linux环境进程间通信----系统 V 消息队列(二)
一、消息队列是一条由消息连接而成的链表,它保存在内核中,通过消息队列的引用标示符来访问。
二、消息队列不同于管道,通信的两个进程可以是完全无关的进程,它们之间不需要约定同步的方法。只要消息队列存在并且有存放消息的空间,发送进程就可以向消息队列中存放消息,并且可以在接收进程开始之前终止其执行。但是使用管道通信的进程,无论是匿名管道还是有名管道,通信的两个进程都必须是正在运行的进程。这一点是消息队列的优点。
三、编写两个程序,第一个是从消息队列中接收消息,第二个程序则发送消息。每一个消息是用户输入的任意字符串,字符串“end”表示输入结束。
1 msqRcv.c:
/* * msqRcv.c * * Created on: Aug 4, 2013 * Author: root */ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> struct my_msg{ long int my_msg_type; char text[BUFSIZ]; } msgbuf; int main(){ int running = 1; int msgid; long int msg_to_receive = 0; msgid=msgget((key_t)56780, 0666|IPC_CREAT); //msgid就是消息队列引用标识符 if(msgid == -1){ printf("msgget failed.\n"); exit(1); } while(running){ if(msgrcv(msgid, (void*)&msgbuf, BUFSIZ, msg_to_receive,0) == -1){ printf("msgrcv failed.\n"); exit(1); } printf("You wrote:%s", msgbuf.text); if(strncmp(msgbuf.text, "end", 3) == 0){ running = 0; } } if(msgctl(msgid, IPC_RMID, 0) == -1){ printf("msgctl(IPC_RMID) failed!\n"); exit(1); } return 0; }
2 msqSend.c:
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> struct my_msg{ long int my_msg_type; char text[BUFSIZ]; } msgbuf; int main(){ int running = 1; int msgid; msgid = msgget((key_t)56780, 0666|IPC_CREAT); if(msgid == -1){ printf("msgget failed.\n"); exit(1); } //msgctl(msgid, IPC_RMID, 0); while(running){ printf("Enter some text:"); fgets(msgbuf.text, BUFSIZ, stdin); msgbuf.my_msg_type = 1; if(msgsnd(msgid, (void*)&msgbuf, BUFSIZ, 0) == -1){ printf("msgsend failed.\n"); exit(1); } if(strncmp(msgbuf.text, "end", 3) == 0){ running = 0; } } return 0; }