IPC通信之消息队列
“消息”是在两台计算机间传送的数据单位。消息可以非常简单,例如只包含文本字符串;也可以更复杂,可能包含嵌入对象
。消息被发送到队列中。“消息队列”是在消息的传输过程中保存消息的容器。消息队列管理器在将消息从它的源中继到它的目标时充当中间人。队列的主要目的是提供路由并保证消息的传递;如果发送消息时接收者不可用,消息队列会保留消息,直到可以成功地传递它。
链式队列

   
M
sqid_ds   维护消息队列的结构体,队列的第一个消息指针msg_first,最后一个消息指针msg_last
消息中有一个成员指针next
管道属于顺序队列,消息队列属于链式队列;
每一个消息中包含有哪些内容:
   Data    数据

   Length  数据的长度

   Type    数据的类型。

  例如:
      1----voltage data
      2----电流数据
      3----有功功率
  消息的接收端可以根据消息的类型来接收。

文件I/O
消息队列
open
msg_get               
read
msgrcv
write
msgsnd
close
msgctrl

(1) msgget(打开消息队列)
所需头文件
#include <sys/types.h>

#include <sys/ipc.h>
#include <sys/msg.h>
函数原型
int msgget(key_t key, int flag);
函数参数
key:和消息队列关联的key
flag:消息队列的访问权限
函数返回值
成功:消息队列ID
出错:-1
  属于链式队列,所以无需队列的大小

(2) msgsnd(消息队列的发送)相当于队列的插入== write
所需头文件
#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;
}

(3)msgrcv(消息队列的接收)相当于队列的删除==read
      
所需头文件
#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
  
 消息队列中数据读后,数据也不存在了
(4)msgctl
所需头文件
#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通信之消息队列)的更多相关文章

  1. 8.7 进程间的通讯:管道、消息队列、共享内存、信号量、信号、Socket

    进程间的通讯 进程间为什么需要通讯? 共享数据.数据传输.消息通知.进程控制 进程间的通讯有哪些类型? 首先,联系前面讲过的知识,进程之间的用户地址空间是相互独立的,不能进行互相访问,但是,内核空间却 ...

  2. Android进阶笔记04:Android进程间通讯(IPC)之Messenger

    一. Android进程间通讯之Messenger 的引入 (1)引言:      平时一说进程间通讯,大家都会想到AIDL,其实messenger和AIDL作用一样,都可以进行进程间通讯.它是基于消 ...

  3. 进程间的通讯(IPC)方式

    内存映射 为什么要进行进程间的通讯(IPC (Inter-process communication)) 数据传输:一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几M字节之间共享数据 ...

  4. Linux学习笔记(六) 进程管理

    1.进程基础 当输入一个命令时,shell 会同时启动一个进程,这种任务与进程分离的方式是 Linux 系统上重要的概念 每个执行的任务都称为进程,在每个进程启动时,系统都会给它指定一个唯一的 ID, ...

  5. Windows进程间通讯(IPC)----消息队列

    消息队列 windows系统是通过消息驱动的,每移动一下鼠标,点击一下屏幕都会产生一个消息.这些消息会先被放在windows的一个系统消息队列(先进先出)中,windows系统会为每一个GUI线程创建 ...

  6. 通信有连接有消息队列选择boost.asio

    通信有连接有消息队列选择boost.asio 连接自主管理 消息队列自主管理

  7. linux io 学习笔记(03)---共享内存,信号灯,消息队列

    system V IPC 1)消息队列 2)共享内存 3)信号灯(信号量集) 1.消息队列. ipcs -q 查看系统中使用消息队列的情况 ipcrm -q +msqid 删除消息队列 消息队列工作原 ...

  8. Android(java)学习笔记232:Android进程间通讯(IPC)之AIDL

    一.IPC inter process communication  进程间通讯 二.AIDL android  interface  defination  language  安卓接口定义语言 满 ...

  9. Android(java)学习笔记175:Android进程间通讯(IPC)之AIDL

    一.IPC inter process communication  进程间通讯 二.AIDL android  interface  defination  language  安卓接口定义语言 满 ...

  10. Windows进程间通讯(IPC)----WM_COPYDATA

    WM_COPYDATA通讯思路 通过向其他进程的窗口过程发送WM_COPYDATA消息可以实现进程间通讯. 只能通过SendMessage发送WM_COPYDATA消息,而不能通过PostMessag ...

随机推荐

  1. git—分支设置

    什么是分支? 项目以上线,但需要开发新的功能.不能直接在项目上进行开发的,这时候就需要创建一个分支,去完成新功能的开发.测试等.完成之后合并到主分支上面.如果新功能的开发不用分支,导致的问题就会有很多 ...

  2. 在Win7的64位系统中安装最新版Eclipse或STS

    Eclipse版本为:eclipse-jee-2021-12-R-win32-x86_64 STS版本为:sts-4.13.1.RELEASE 这两个版本中都自带了17.0.1的jre插件,默认会使用 ...

  3. ZooKeeper启动报错,未成功开启服务

    1.问题示例 (1)启动ZooKeeper服务报错 [Hadoop@master ~]$ zkServer.sh statusZooKeeper JMX enabled by defaultUsing ...

  4. element中表格中对其解决方法:

    element中表格中对其解决方法: 一开始错位的表格的样式:​ 发现我们设置的align="center"居中没人用  后面是操作列里的按钮影响了它   直接把align里的属性 ...

  5. Linux 截图快捷键 - 搬运

    Linux 截图快捷键 转自:linux 截图快捷键 环境 Linux Mint  21.1 1. Prt ScSysRq ---->全屏截图2. Shift+Prt ScSysRq ----& ...

  6. 【转载】Python:logging详细版

    转载自:https://www.cnblogs.com/Nicholas0707/p/9021672.html 一.logging模块 (一).日志相关概念 日志是一种可以追踪某些软件运行时所发生事件 ...

  7. 基于 Istio 的灰度发布架构方案实践之路

    作者:京东物流 赵勇萍 1. 背景介绍 灰度发布,又名金丝雀发布,是指能够平滑过渡的一种发布方式.基于系统稳定性和快速业务迭代的综合考虑,业务应用开发团队采取了新版本服务灰度上线的方式,即新版本服务并 ...

  8. 在Linux中安装containerd作为kubernetes的容器运行时

    概述 从kubernetes1.24开始的版本移除了内置的docker支持,用户可以自行选择需要使用的容器运行时,比如containerd.CRI-O.Docker Engine等等,这里我们采用二进 ...

  9. 有奖征文活动:从 RTC 到 RTE,从音视频到「实时万象」!

    Hi 小伙伴们, 社区已经更名 RTE 两个月辣-大家对于 RTC 和 RTE 的区分,是否还有疑惑呢? 关于这两者的区别,我们创始人兼 CEO 赵斌老师说: "RTC(实时音视频)从 Co ...

  10. 【读书笔记】组合计数中的行列式方法 专题3 完美匹配: the Pfaffian method

    目录 专题3-Perfect matchings: the Pfaffian method 一些定义 用2×1的砖密铺a×b的大矩形的方法数 专题3-Perfect matchings: the Pfa ...