【Linux之进程间通信】
项目代码获取:https://gitee.com/chenshao777/linux-processes.git
(麻烦点个免费的Star哦,您的Star就是我的写作动力!)
07.消息队列
1.创建消息队列
int msgget(key_t key, int msgflg);
参数 | 含义 |
---|---|
key | 生成msgid相关的key值 |
msgflg | 权限 |
需要包含头文件
#include
#include
#include
2.删除消息队列对象
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
参数 | 含义 |
---|---|
msqid | msgid |
cmd | 命令参数(IPC_RMID:删除,IPC_STAT:查看状态…) |
buf | cmd=IPC_SET时该参数用于设置属性 |
需要包含头文件
#include
#include
#include
3.写消息队列
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
参数 | 含义 |
---|---|
msqid | msgid |
msgp | msg结构体(至少包括type、text两个成员) |
msgsz | msg结构体中text数组 |
msgflg | 0:阻塞至消息写完 IPC_NOWAIT:当消息队列已满的时候,msgsnd函数不等待立即返回 IPC_NOERROR:若发送的消息大于size字节,则把该消息截断,截断部分将被丢弃,且不通知发送进程。 |
需要包含头文件
#include
#include
#include
4.读消息队列
ssize_t msgrcv(int msqid,
void *msgp,
size_t msgsz,
long msgtyp,
int msgflg);
参数 | 含义 |
---|---|
msqid | msgid |
msgp | 接收缓冲区 |
msgsz | 接收的数据长度 |
msgtyp | 0:接收第一个消息 >0:接收类型等于msgtyp的第一个消息 <0:接收类型等于或者小于msgtyp绝对值的第一个消息 |
msgflg | 0: 阻塞式接收消息,没有该类型的消息msgrcv函数一直阻塞等待 IPC_NOWAIT:如果没有返回条件的消息调用立即返回,此时错误码为ENOMSG IPC_EXCEPT:与msgtype配合使用返回队列中第一个类型不为msgtype的消息 IPC_NOERROR:如果队列中满足条件的消息内容大于所请求的size字节,则把该消息截断,截断部分将被丢弃 |
需要包含头文件
#include
#include
#include
5.消息队列特点
6.两个进程间通信代码示例
进程1
#include
#include
#include
#include
#include
#include
#include
//消息结构体
struct msg_struct{
long type;
char text[128];
};
void handler(int sig)
{
return;
}
int main(int argc, char *argv[])
{
int msg_id;
int key;
key = ftok("./a.c",1);
//亲缘进程消息队列
msg_id = msgget(key, IPC_CREAT | 0777);
if(msg_id < 0){
printf("创建消息队列失败\n");
}
//初始化消息
struct msg_struct msgsend, msgrecv;
int pid;
pid = fork();
if(pid > 0){
msgsend.type = 100;
printf("父进程负责发送\n");
while(1){
//从键盘获取
fgets(msgsend.text, 128, stdin);
//写入信号队列
msgsnd(msg_id, (const void*)&msgsend, 128, 0);
}
}
else if(pid == 0){
printf("子进程负责接收\n");
while(1)
{
memset(msgrecv.text,0,128);
msgrcv(msg_id,(void*)&msgrecv,128,200,0);
printf("接收到:%s",msgrecv.text);
}
}
return 0;
}
进程2
#include
#include
#include
#include
#include
#include
#include
//消息结构体
struct msg_struct{
long type;
char text[128];
};
void handler(int sig)
{
return;
}
int main(int argc, char *argv[])
{
int msg_id;
int key;
key = ftok("./a.c",1);
//亲缘进程消息队列
msg_id = msgget(key, IPC_CREAT | 0777);
if(msg_id < 0){
printf("创建消息队列失败\n");
}
//初始化消息
struct msg_struct msgsend, msgrecv;
int pid;
pid = fork();
if(pid > 0){
msgsend.type = 200;
printf("父进程负责发送\n");
while(1){
//从键盘获取
fgets(msgsend.text, 128, stdin);
//写入信号队列
msgsnd(msg_id, (const void*)&msgsend, 128, 0);
}
}
else if(pid == 0){
printf("子进程负责接收\n");
while(1)
{
memset(msgrecv.text,0,128);
msgrcv(msg_id,(void*)&msgrecv,128,100,0);
printf("接收到:%s",msgrecv.text);
}
}
return 0;
}
运行结果:
进程1
hc@hc-vm:~/Linux_ARM/git/linux-processes/06.消息队列$ ./write
父进程负责发送
子进程负责接收
接收到:123
接收到:456
abc
aaa
进程2
hc@hc-vm:~/Linux_ARM/git/linux-processes/06.消息队列$ ./read
父进程负责发送
子进程负责接收
123
456
接收到:abc
接收到:aaa