笔记六:进程间的通信(IPC通信之消息队列)
。消息被发送到队列中。“消息队列”是在消息的传输过程中保存消息的容器。消息队列管理器在将消息从它的源中继到它的目标时充当中间人。队列的主要目的是提供路由并保证消息的传递;如果发送消息时接收者不可用,消息队列会保留消息,直到可以成功地传递它。
sqid_ds 维护消息队列的结构体,队列的第一个消息指针msg_first,最后一个消息指针msg_last
|
文件I/O
|
消息队列
|
|
open
|
msg_get
|
|
read
|
msgrcv
|
|
write
|
msgsnd
|
|
close
|
msgctrl
|
|
所需头文件
|
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
|
|
函数原型
|
int msgget(key_t key, int flag);
|
|
函数参数
|
key:和消息队列关联的key值
|
|
flag:消息队列的访问权限
|
|
|
函数返回值
|
成功:消息队列ID
|
|
出错:-1
|
|
所需头文件
|
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
|
|
|
函数原型
|
int msgsnd(int msqid, const void *msgp, size_t size, int flag);
|
|
|
函数参数
|
msqid:消息队列的ID
|
|
| msgp:指向消息的指针。常用消息结构msgbuf如下:
struct msgbuf
{
long mtype; //消息类型
char mtext[N] //消息正文
};
|
||
|
size:发送的消息正文的字节数
|
||
|
flag:
|
IPC_NOWAIT 消息没有发送完成函数也会立即返回。
|
|
|
0:直到发送完成函数才返回
|
||
|
函数返回值
|
成功:0
|
|
|
出错:-1
|
||
#include "sys/ipc.h"
#include "sys/msg.h"
#include "sys/types.h"
#include "stdio.h"
struct mybuf
{
long mytype;
char sendbuf[128];
};
int main()
{
int key;
int msgid;
struct mybuf wrbuf,rdbuf;
key=ftok("./a.c",'a');
if(key < 0)
{
printf("creat key failure\n");
return -1;
}
msgid=msgget(key,IPC_CREAT | 0777);
if(msgid < 0)
{
printf("creat message queue failure\n");
return -2;
}
wrbuf.mytype=10;// voltage data
printf("please input data:\n");
fgets(wrbuf.sendbuf,128,stdin);
msgsnd(msgid,(void *)&wrbuf,128,0);
system("ipcs -q");
//read
msgrcv(msgid,(void *)&rdbuf,128,11,0);
printf("%s",rdbuf.sendbuf);
system("ipcs -q");
msgctl(msgid,IPC_RMID,NULL);
return 0;
}
|
所需头文件
|
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
|
|
|
函数原型
|
int msgrcv(int msgid, void* msgp, size_t size, long msgtype, int flag);
|
|
|
函数参数
|
msqid:消息队列的ID
|
|
|
msgp:接收消息的缓冲区
|
||
|
size:要接收的消息的字节数
|
||
|
msgtype:
|
0:接收消息队列中第一个消息。
|
|
|
大于0:接收消息队列中第一个类型为msgtyp的消息.
|
||
|
小于0:接收消息队列中类型值不大于msgtyp的绝对值且类型值又最小的消息。
|
||
|
flag:
|
0:若无消息函数会一直阻塞
|
|
|
IPC_NOWAIT:若没有消息,进程会立即返回ENOMSG。
|
||
|
函数返回值
|
成功:接收到的消息的长度
|
|
|
出错:-1
|
||
|
所需头文件
|
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
|
|
|
函数原型
|
int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );
|
|
|
函数参数
|
msqid:消息队列的队列ID
|
|
|
|
cmd:
|
IPC_STAT:读取消息队列的属性,并将其保存在buf指向的缓冲区中。
|
|
|
|
IPC_SET:设置消息队列的属性。这个值取自buf参数。
|
|
|
|
IPC_RMID:从系统中删除消息队列。
|
|
|
buf:消息队列缓冲区
|
|
|
函数返回值
|
成功:0
|
|
|
|
出错:-1
|
|
server.c 端
#include "sys/ipc.h"
#include "sys/msg.h"
#include "sys/types.h"
#include "stdio.h"
#include "string.h"
struct mybuf
{
long mytype;
char sendbuf[128];
};
int main()
{
int key;
int msgid;
int pid;
struct mybuf wrbuf,rdbuf;
key=ftok("./a.c",'a');
if(key < 0)
{
printf("creat key failure\n");
return -1;
}
msgid=msgget(key,IPC_CREAT | 0777);
if(msgid < 0)
{
printf("creat message queue failure\n");
return -2;
}
pid=fork();
if(pid < 0)
return -3;
if(pid > 0)//write type=10
{
wrbuf.mytype=10;// voltage data
while(1)
{
memset(wrbuf.sendbuf,0,128);
printf("please input data:\n");
fgets(wrbuf.sendbuf,128,stdin);
msgsnd(msgid,(void *)&wrbuf,128,0);
}
}
//read
if(pid == 0) //read type=11
{
while(1)
{
memset(rdbuf.sendbuf,0,128);
msgrcv(msgid,(void *)&rdbuf,128,11,0);
printf("%s",rdbuf.sendbuf);
}
}
msgctl(msgid,IPC_RMID,NULL);
return 0;
}
client.c 端
#include "sys/ipc.h"
#include "sys/msg.h"
#include "sys/types.h"
#include "stdio.h"
#include "string.h"
struct mybuf
{
long mytype;
char sendbuf[128];
};
int main()
{
int key;
int msgid;
int pid;
struct mybuf wrbuf,rdbuf;
key=ftok("./a.c",'a');
if(key < 0)
{
printf("creat key failure\n");
return -1;
}
msgid=msgget(key,IPC_CREAT | 0777);
if(msgid < 0)
{
printf("creat message queue failure\n");
return -2;
}
pid=fork();
if(pid < 0)
return -3;
if(pid > 0)//write type=10
{
wrbuf.mytype=11;// voltage data
while(1)
{
memset(wrbuf.sendbuf,0,128);
printf("please input data:\n");
fgets(wrbuf.sendbuf,128,stdin);
msgsnd(msgid,(void *)&wrbuf,128,0);
}
}
//read
if(pid == 0) //read type=11
{
while(1)
{
memset(rdbuf.sendbuf,0,128);
msgrcv(msgid,(void *)&rdbuf,128,10,0);
printf("%s",rdbuf.sendbuf);
}
}
msgctl(msgid,IPC_RMID,NULL);
return 0;
}
笔记六:进程间的通信(IPC通信之消息队列)的更多相关文章
- 8.7 进程间的通讯:管道、消息队列、共享内存、信号量、信号、Socket
进程间的通讯 进程间为什么需要通讯? 共享数据.数据传输.消息通知.进程控制 进程间的通讯有哪些类型? 首先,联系前面讲过的知识,进程之间的用户地址空间是相互独立的,不能进行互相访问,但是,内核空间却 ...
- Android进阶笔记04:Android进程间通讯(IPC)之Messenger
一. Android进程间通讯之Messenger 的引入 (1)引言: 平时一说进程间通讯,大家都会想到AIDL,其实messenger和AIDL作用一样,都可以进行进程间通讯.它是基于消 ...
- 进程间的通讯(IPC)方式
内存映射 为什么要进行进程间的通讯(IPC (Inter-process communication)) 数据传输:一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几M字节之间共享数据 ...
- Linux学习笔记(六) 进程管理
1.进程基础 当输入一个命令时,shell 会同时启动一个进程,这种任务与进程分离的方式是 Linux 系统上重要的概念 每个执行的任务都称为进程,在每个进程启动时,系统都会给它指定一个唯一的 ID, ...
- Windows进程间通讯(IPC)----消息队列
消息队列 windows系统是通过消息驱动的,每移动一下鼠标,点击一下屏幕都会产生一个消息.这些消息会先被放在windows的一个系统消息队列(先进先出)中,windows系统会为每一个GUI线程创建 ...
- 通信有连接有消息队列选择boost.asio
通信有连接有消息队列选择boost.asio 连接自主管理 消息队列自主管理
- linux io 学习笔记(03)---共享内存,信号灯,消息队列
system V IPC 1)消息队列 2)共享内存 3)信号灯(信号量集) 1.消息队列. ipcs -q 查看系统中使用消息队列的情况 ipcrm -q +msqid 删除消息队列 消息队列工作原 ...
- Android(java)学习笔记232:Android进程间通讯(IPC)之AIDL
一.IPC inter process communication 进程间通讯 二.AIDL android interface defination language 安卓接口定义语言 满 ...
- Android(java)学习笔记175:Android进程间通讯(IPC)之AIDL
一.IPC inter process communication 进程间通讯 二.AIDL android interface defination language 安卓接口定义语言 满 ...
- Windows进程间通讯(IPC)----WM_COPYDATA
WM_COPYDATA通讯思路 通过向其他进程的窗口过程发送WM_COPYDATA消息可以实现进程间通讯. 只能通过SendMessage发送WM_COPYDATA消息,而不能通过PostMessag ...
随机推荐
- Python之路径处理
路径处理,需导入 os包 1 import os # 导入 os 包 2 3 """获取运行脚本文件夹的路径""" 4 current_di ...
- JSP环境搭建及入门 和 虚拟路径和虚拟主机
Jsp:是一个动态网页,而不是静态网页 html,css,js,Jquery:是静态网页 动态网页是随着,时间,地点,用户操作,而改变 静态不需要jsp 动态是需要的 BS 可以通过浏览器直接访问浏览 ...
- BLE目录
CH58x/CH57x 蓝牙从机篇(Peripheral) CH573 CH582 CH579蓝牙从机(Peripheral)/主机(Central)例程讲解一(蓝牙主从机收发数据接口说明) CH57 ...
- 2021.06.18 思科anyconnect安全移动客户端通知
mac系统更新后,开关机后都会弹出思科anyconnect安全移动客户端通知的弹框,很烦,所以要干掉它! 打开终端,执行以下两行命令即可: cd /Library/LaunchAgents/ mv / ...
- el-admin登录详解
1.进入登陆界面后,就会自动获取验证码. 2.前端访问auth/code接口获取后端生成的验证码(包括uuid,img,结果值),然后放入redis,设置2分钟过期,并返回识别码.图片url给前端. ...
- PO、VO、DAO、BO、DTO、POJO 之间的区别
PO(Persistant Object),持久对象 这个对象是与数据库中的表相映射的Java对象. VO(Value Object),值对象 通常用于业务层之间的数据传递,和PO一样也是仅仅包含数据 ...
- 说来惭愧,关于Session的某块知识的学习,感觉涨了知识
Session的查漏补缺 今天在写界面的时候,想要利用servlet和jsp页面实现界面的跳转,之前实现这些内容的时候,我是没有用到session来实现这个功能的. 直到今天,想要将第一个界面的数据隔 ...
- 02.SQL
1. SQL通用语法 SQL语句可以单行或者多行书写,以分号结尾 SQL语句可以使用空格或者缩进来增强语句的可读性 MYSQL数据库的SQL语句不区分大小写,关键字建议使用大写 注释: 单行注释:-- ...
- TCP 三次握手,给我长脸了噢
大家好,我是小富~ 个人资源分享网站:FIRE 本文收录在 Springboot-Notebook 面试锦集 前言 之前有个小伙伴在技术交流群里咨询过一个问题,我当时还给提供了点排查思路,是个典型的八 ...
- 布局管理器wx.BoxSizer
b = wx.BoxSizer( wx.VERTICAL ) b.Add(self.notebook1, 1, wx.EXPAND) self.parent.SetSizer(b) 解析以上代码原理, ...