示例程序
接收端
//MsgrcvDemo.c 接收端
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/msg.h>
#define MAX_TEXT 512
struct MSG_TEST {
long int mFlag;
char data[MAX_TEXT];
};
int main(){
int index = 0;
int msgid;
struct MSG_TEST m_message;
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
printf("%s : msgid=%d\n", __FILE__, msgid);
if (msgid == -1) {
fprintf(stderr, "msgget failed with error: %d\n", errno);
exit(EXIT_FAILURE);
}
while(1) {
if (msgrcv(msgid, (void *)&m_message, MAX_TEXT,0,0) == -1) {
fprintf(stderr, "msgrcv failed with error: %d\n", errno);
exit(EXIT_FAILURE);
}
printf("receiver : %s\n", m_message.data);
if (strcmp(m_message.data, "message_04") == 0) {
break;
}
}
if (msgctl(msgid, IPC_RMID, 0) == -1) { // 删除消息队列
fprintf(stderr, "msgctl(IPC_RMID) failed\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
发送端
// MsgsndDemo.c 发送端
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/msg.h>
#define MAX_TEXT 512
struct MSG_TEST {
long int mFlag;
char data[MAX_TEXT];
};// 两方消息格式一致即可
int main(){
struct MSG_TEST m_message;
int msgid;
char buffer[BUFSIZ];
int index = 0;
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
printf("%s : msgid=%d\n", __FILE__, msgid);
if (msgid == -1) {
fprintf(stderr, "msgget failed with error: %d\n", errno);
exit(EXIT_FAILURE);
}
while(index < 5) {
sprintf(m_message.data, "message_%02d", index++);
sleep(1);
printf("send : %s\n", m_message.data);
if (msgsnd(msgid, (void *)&m_message, MAX_TEXT, 0) == -1) {
fprintf(stderr, "msgsnd failed\n");
exit(EXIT_FAILURE);
}
}
exit(EXIT_SUCCESS);
}
分别启动接收端和发送端两个应用程序。每隔1秒,接收端收到一次发送端的数据;
函数解析:
int msgget(key_t key, int msgflg);
从内核的消息队列中取出一个消息队列的实例。
获取方式 msgflg:
IPC_PRIVATE: 创建一个该进程独占的消息队列,其它进程不能访问该消息队列
IPC_CREAT: 若消息队列不存在,创建一个新的消息队列,若消息队列存在,返回存在的消息队列,系统范围内使用
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
向指定的消息队列中发送一条信息。
msgflg 表示是否阻塞(0表示阻塞方式,设置IPC_NOWAIT 表示非阻塞方式)
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
从指定的消息队列中取出一条信息。
msgtyp 决定从队列中返回哪条消息(0表示返回消息队列中第一条消息)
msgflg 表示是否阻塞(0表示阻塞方式,设置IPC_NOWAIT 表示非阻塞方式)
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
执行一条相关的消息队列操作命令。
这里是移除消息队列(IPC_RMID)。
消息队列是独立于应用程序之外,一旦生成,由内核维护。
使用shell命令可以查看
ipcs -q
查看当前用户范围下的内核中存在的消息队列
如果没有使用msgctl(IPC_RMID)等相关函数去移除队列,则该队列一直存在于系统中;
部分常用命令
ipcs -a 是默认的输出信息 打印出当前系统中所有的进程间通信方式的信息
ipcs -m 打印出使用共享内存进行进程间通信的信息
ipcs -q 打印出使用消息队列进行进程间通信的信息
ipcs -s 打印出使用信号进行进程间通信的信息
ipcrm -M shmkey 移除用shmkey创建的共享内存段
ipcrm -m shmid 移除用shmid标识的共享内存段
ipcrm -Q msgkey 移除用msqkey创建的消息队列
ipcrm -q msqid 移除用msqid标识的消息队列
ipcrm -S semkey 移除用semkey创建的信号
ipcrm -s semid 移除用semid标识的信号