一、系统V IPC

三种系统V IPC:消息队列、信号量以及共享内存(共享存储器)之间有很多相似之处。

每个内核中的 I P C结构(消息队列、信号量或共享存储段)都用一个非负整数的标识符( i d e n t i f i e r )加以引用。

无论何时创建I P C结构(调用m s g g e t、 s e m g e t或s h m g e t) ,都应指定一个关键字(k e y),关键字的数据类型由系统规定为 k e y _ t,通常在头文件< s y s / t y p e s . h >中被规定为长整型。关键字由内核变换成标识符。

以上简单介绍了IPC,对接下来介绍的消息队列、信号量和共享内存有助于理解。

二、消息队列

1、简介

消息队列是消息的链接表 ,存放在内核中并由消息队列标识符标识。我们将称消息队列为 “队列”,其标识符为“队列 I D”。 m s g g e t用于创建一个新队列或打开一个现存的队列。 m s g s n d用于将新消息添加到队列尾端。每个消息包含一个正长整型类型字段,一个非负长度以及实际数据字节(对应于长度),所有这些都在将消息添加到队列时,传送给 m s g s n d。 m s g r c v用于从队列中取消息。我们并不一定要以先进先出次序取消息,也可以按消息的类型字段取消息。

2、函数介绍

ftok函数

#include

#include

key_t ftok(const char *pathname, int proj_id);//“/home/linux” , 'a'

功能:生成一个key(键值)

msgget函数

#include

#include

#include

int msgget(key_t key, int msgflg);

功能:创建或取得一个消息队列对象

返回:消息队列对象的id 同一个key得到同一个对象

格式:msgget(key,flag|mode);

flag:可以是0或者IPC_CREAT(不存在就创建)

mode:同文件权限一样

msgsnd函数

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

功能:将msgp消息写入标识为msgid的消息队列

msgp:

struct msgbuf {

long mtype; /* message type, must be > 0 */消息的类型必须>0

char mtext[1]; /* message data */长度随意

};

msgsz:要发送的消息的大小 不包括消息的类型占用的4个字节

msgflg: 如果是0 当消息队列为满 msgsnd会阻塞

如果是IPC_NOWAIT 当消息队列为满时 不阻塞 立即返回

返回值:成功返回id 失败返回-1

msgrcv函数

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,

int msgflg);

功能:从标识符为msgid的消息队列里接收一个指定类型的消息 并 存储于msgp中 读取后 把消息从消息队列中删除

msgtyp:为 0 表示无论什么类型 都可以接收

msgp:存放消息的结构体

msgsz:要接收的消息的大小 不包含消息类型占用的4字节

msgflg:如果是0 标识如果没有指定类型的消息 就一直等待

如果是IPC_NOWAIT 则表示不等待

msgctl函数

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

msgctl(msgid,IPC_RMID,NULL);//删除消息队列对象

程序2-2将简单演示消息队列:

---  snd.c  ---

#include "my.h"

typedef struct{

long type;

char name[20];

int age;

}Msg;

int main()

{

key_t key = ftok("/home/liudw",'6');

printf("key:%x\n",key);

int msgid = msgget(key,IPC_CREAT|O_WRONLY|0777);

if(msgid<0)

{

perror("msgget error!");

exit(-1);

}

Msg m;

puts("please input your type name age:");

scanf("%ld%s%d",&m.type,m.name,&m.age);

msgsnd(msgid,&m,sizeof(m)-sizeof(m.type),0);

return 0;

}

---  rcv.c  ---

#include "my.h"

typedef struct{

long type;

char name[20];

int age;

}Msg;

int main()

{

key_t key = ftok("/home/liudw",'6');

printf("key:%x\n",key);

int msgid = msgget(key,O_RDONLY);

if(msgid<0)

{

perror("msgget error!");

exit(-1);

}

Msg rcv;

long type;

puts("please input type you want!");

scanf("%ld",&type);

msgrcv(msgid,&rcv,sizeof(rcv)-sizeof(type),type,0);

printf("rcv--name:%s age:%d\n",rcv.name,rcv.age);

msgctl(msgid,IPC_RMID,NULL);

return 0;

}

运行演示:

三、详解ftok函数

ftok根据路径名,提取文件信息,再根据这些文件信息及project ID合成key,该路径可以随便设置。

该路径是必须存在的,ftok只是根据文件inode在系统内的唯一性来取一个数值,和文件的权限无关。

proj_id是可以根据自己的约定,随意设置。这个数字,有的称之为project ID; 在UNIX系统上,它的取值是1到255;

为了验证以上观点,对程序2-2稍作修改,将路径和proj_id修改:

程序3-1如下:

---  snd.c  ---

#include "my.h"

typedef struct{

long type;

char name[20];

int age;

}Msg;

int main()

{

key_t key = ftok("/home",'a');

printf("key:%x\n",key);

int msgid = msgget(key,IPC_CREAT|O_WRONLY|0777);

if(msgid<0)

{

perror("msgget error!");

exit(-1);

}

Msg m;

puts("please input your type name age:");

scanf("%ld%s%d",&m.type,m.name,&m.age);

msgsnd(msgid,&m,sizeof(m)-sizeof(m.type),0);

return 0;

}

---  rcv.c  ---

#include "my.h"

typedef struct{

long type;

char name[20];

int age;

}Msg;

int main()

{

key_t key = ftok("/home",'a');

printf("key:%x\n",key);

int msgid = msgget(key,O_RDONLY);

if(msgid<0)

{

perror("msgget error!");

exit(-1);

}

Msg rcv;

long type;

puts("please input type you want!");

scanf("%ld",&type);

msgrcv(msgid,&rcv,sizeof(rcv)-sizeof(type),type,0);

printf("rcv--name:%s age:%d\n",rcv.name,rcv.age);

msgctl(msgid,IPC_RMID,NULL);

return 0;

}

运行演示如下图:

 

总结:主要介绍了进程间通信的消息队列。

linux 消息对lie_Linux进程间通信之消息队列总结相关推荐

  1. 【Linux系统编程】进程间通信之消息队列

    00. 目录 文章目录 00. 目录 01. 消息队列概述 02. 消息队列相关函数 03. 消息队列读写操作 04. 测试代码 05. 附录 01. 消息队列概述 消息队列提供了一种在两个不相关的进 ...

  2. linux 消息对lie_Linux系统编程—消息队列

    1.消息队列简介 消息队列本质上是位于内核空间的链表,链表的每个节点都是一条消息.每一条消息都有自己的消息类型,消息类型用整数来表示,而且必须大于 0.每种类型的消息都被对应的链表所维护: 图1 位于 ...

  3. Linux进程间通信——使用消息队列

    下面来说说如何用不用消息队列来进行进程间的通信,消息队列与命名管道有很多相似之处.有关命名管道的更多内容可以参阅我的另一篇文章:Linux进程间通信--使用命名管道 一.什么是消息队列 消息队列提供了 ...

  4. Linux(信号,进程间通信)共享内存,信号量,消息队列

    信号(signal) 1.1 什么是信号? 信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式 1.2 信号的来源 硬件 [1] 用户在终端按下某些键时,终端驱动程序会发送信号给前台进程 ct ...

  5. linux用函数输出进程信息,进程间通信之-消息队列(Message)--linux内核剖析(十一)...

    消息队列 消息队列 (也叫做报文队列)是Unix系统V版本中3种进程间通信机制之一.另外两种是信号量和共享内存. 这些IPC机制使用共同的授权方法.只有通过系统调用将标志符传递给核心之后,进程才能存取 ...

  6. c语言系统编程八:Linux进程间通信之消息队列

    Linux进程间通信之消息队列 一 消息队列概述 二 消息队列的特点 三 消息队列的创建和使用 3.1 获取系统唯一的key值 3.2 创建消息队列 3.3 查看消息队列和删除消息队列的shell命令 ...

  7. Linux进程间通信(IPC)-------消息队列

    消息队列是进程间通信的一种方法,他有两个操作,一个进程来发送消息(也就是向内存中写入数据),另一个是获取消息(也就是另外一个进程在内存中读取数据) 下面来看消息队列的 创建,写入,读取等需要用到的函数 ...

  8. linux消息通信无法接收,进程间通信:消息队列有关问题:进程1接收不到进程2的消息...

    进程间通信:消息队列有关问题:进程1接收不到进程2的消息 进程间通信:消息队列有关问题:进程1接收不到进程2的消息 日期:2014-05-16 浏览次数:20365 次 进程间通信:消息队列问题:进程 ...

  9. 【Linux系统编程】进程间通信--消息队列

    概述 消息队列提供了一种在两个不相关的进程之间传递数据的简单高效的方法,其特点如下: 1)消息队列可以实现消息的随机查询.消息不一定要以先进先出的次序读取,编程时可以按消息的类型读取. 2)消息队列允 ...

最新文章

  1. 如何通过机器学习还原图像色彩
  2. Socket接收器——Acceptor
  3. 【代码段】UIView 部分圆角
  4. javaweb学习总结三(枚举)
  5. (三)html5的结构
  6. 计算机游戏和传统游戏的区别是什么,电竞显示器与普通显示器有什么区别-电脑自学网...
  7. 安徽省2012年下半年计算机水平考试(二级 c语言程序设计),安徽省计算机等级二级考试真题C语言2012年12月...
  8. MySQL Group Replication数据安全性保障
  9. lstm 输入数据维度_理解Pytorch中LSTM的输入输出参数含义
  10. linux jvm启动过程,Linux操作系统启动过程详解
  11. 如何使用 Mac 中的“信息”?
  12. Atitit保证架构超前性 前瞻性 目录 第一章 为什么需要修改代码 1 第一节 业务增加功能 1 第二节 增加字段 1 第三节 增加表数据需要查询 修改 1 第四节 类库升级 1 第二章 简单抽象
  13. 【C++】图书管理系统(含全部源代码)
  14. TOGAF架构学习总结
  15. python爬取快手视频并批量下载
  16. 无人机辅助移动边缘计算的计算卸载优化:一种深度确定性策略梯度方法(6)——代码实现
  17. Himawari8注册后发来信息下载数据
  18. 医疗器械信息系统分析
  19. 公差基本偏差代号_基本偏差代号怎么确定
  20. 百度分享支持https

热门文章

  1. ExtJS学习--------Ext.Element中的经常使用事件和其它重要的方法学习(实例)
  2. 垃圾回收机制的优点和原理
  3. TabControl控件
  4. SQL重置数据表id
  5. /usr/local/php-5.2.14/sbin/php-fpm start Starting php_fpm –fpm-config
  6. c语言 getchar_C语言gets输入问题
  7. hive explode
  8. esxi虚拟化集群_ProxmoxVE 之集群安装(V5.2)
  9. matlab 叠加 area,[转载]matlab学习——area填色图
  10. django的环境搭建(一)