文章目录

  • IPC对象
    • 查看已经创建的IPC对象:
  • 消息队列概述
    • 消息队列的概念
    • 消息队列的特点
    • 在ubuntu 12.04中消息队列限制值如下
    • ftok函数
    • 创建消息队列 -- msgget( )
    • 发送消息 -- msgsnd( )
    • 接收消息 -- msgrcv( )
    • 消息队列的控制

IPC对象

除了最原始的进程间通信方式信号、无名管道和有名管道外,还有三种进程间通信方式,这 三种方式称之为IPC对象。
IPC对象分类:消息队列、共享内存、信号灯集。
IPC对象也是在内核空间开辟区域,每一种IPC对象创建好之后都会将其设置为全局,并且会给其分配一个编号,只要找到唯一的这个编号就可以进行通信,所以不相关的进程可以通过IPC对象通信IPC对象创建好之后,会在当前系统中可见,只要不删除或者不关闭系统,就会一直存在。

查看已经创建的IPC对象:

ipcs 查看当前系统中所有创建的IPC对象
ipcs ‐q 查看创建的消息队列
ipcs ‐m 查看创建的共享内存
ipcs ‐s 查看信号量
ipcrm 删除IPC对象
例如:ipcrm ‐q msqid 删除标号为msqid的消息队列


消息队列概述

消息队列的概念

消息队列是消息的链表,存放在内存中,由内核维护。

消息队列的特点

1、消息队列中的消息是有类型的。
2、消息队列中的消息是有格式的。
3、消息队列可以实现消息的随机查询。消息不一定要以先进先出的次序读取,编程时可以 按消息的类型读取。
4、消息队列允许一个或多个进程向它写入或者读取消息。
5、与无名管道、命名管道一样,从消息队列中读出消息,消息队列中对应的数据都会被删 除。
6、每个消息队列都有消息队列标识符,消息队列的标识符在整个系统中是唯一的。
7、只有内核重启或人工删除消息队列时,该消息队列才会被删除。若不人工删除消息队 列,消息队列会一直存在于系统中。

在ubuntu 12.04中消息队列限制值如下

每个消息内容最多为8K字节 。
每个消息队列容量最多为16K字节 。
系统中消息队列个数最多为1609个 。
系统中消息个数最多为16384个 。
System V提供的IPC通信机制需要一个key值,通过key值就可在系统内获得一个唯
一的消 息队列标识符。 key值可以是人为指定的,也可以通过ftok函数获得。 如
果多个进程想通过IPC对象通信,则必须找到唯一的标识,而唯一的标识是由key
决定 的,所以只要key知道,则就可以实现多个进程通信。

ftok函数


使用ftok函数获取键值,只要保证ftok的第一个参数对应的文件和第二个参数值相同,则不管程序运行多少遍或者多少个进程或者键值,键值一定都是唯一的。
例子

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
int main(int argc, char const *argv[])
{//使用ftok函数获取键值//只要保证ftok的第一个参数对应的文件和第二个参数值相同,则不管程序运行多少遍或者多少个进程或者键值//键值一定都是唯一的key_t mykey;if((mykey = ftok(".", 100)) == -1){perror("fail to ftok");exit(1);}printf("key = %#x\n", mykey);return 0;
}

创建消息队列 – msgget( )


例子

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int main(int argc, char const *argv[])
{//通过ftok函数获取ipc键值key_t mykey;if((mykey = ftok(".", 100)) == -1){perror("fail to ftok");exit(1);}printf("mykey = %#x\n", mykey);//通过msgget函数创建一个消息队列int msqid;if((msqid = msgget(mykey, IPC_CREAT | 0666)) == -1){perror("fail to msgget");exit(1);}printf("msqid = %d\n", msqid);system("ipcs -q");return 0;
}

发送消息 – msgsnd( )


例子

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
//发送数据并接收回复    全双工通讯
struct msgbuf
{long mtype;       char mtext[128];
};
int main()
{struct msgbuf sendBuf={888,"this is message from quen"};struct msgbuf readBuf;key_t key;key=ftok(".",'z');                              //当前路径printf("key=%x\n",key);   //int msgget(key_t key, int flag);              创建消息队列//int msgId=msgget(0x1235,IPC_CREAT|0777);        如果没有就创建 权限是可读可写可执行int msgId=msgget(key,IPC_CREAT|0777);if(msgId==-1){printf("get que failuer\n");}// int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);msgsnd(msgId,&sendBuf,strlen(sendBuf.mtext),0);       //以非阻塞方式发送 发送给getprintf("send over\n");msgrcv(msgId,&readBuf,sizeof(readBuf.mtext),988,0);   //接收从get来的感谢printf("return from get:%s\n",readBuf.mtext);msgctl(msgId,IPC_RMID,NULL);                             //把创建的消息队列删除释放内存return 0;
}

接收消息 – msgrcv( )


注意:如果没有第四个参数指定的消息时,msgrcv函数会阻塞等待。
如果第四个参数为0,则按照先进先出的方式读取数据 。
if(msgrcv(msgid, &msg, MSGTEXT_SIZE, 0, 0) == ‐1)
如果第四个参数为>0,则获取当前值得消息类型的数据 。
if(msgrcv(msgid, &msg, MSGTEXT_SIZE, 2, 0) == ‐1)
如果第四个参数为<0,则获取当前值得绝对值内消息类型最小的数据。
例子

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
//收到数据并回复感谢   全双工通讯
struct msgbuf
{long mtype;       char mtext[128];
};
int main()
{struct msgbuf readBuf;key_t key;key=ftok(".",'z');                              //当前路径printf("key=%x\n",key);                         //用16进制打印出来//int msgget(key_t key, int flag);              创建消息队列//int msgId=msgget(0x1235,IPC_CREAT|0777);        如果没有就创建 权限是可读可写可执行int msgId=msgget(key,IPC_CREAT|0777); if(msgId==-1){printf("get que failuer\n");}//int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);msgrcv(msgId,&readBuf,sizeof(readBuf.mtext),888,0);      //0默认的方式接受消息 读不到888类型的消息会一直阻塞printf("read from que:%s\n",readBuf.mtext);        struct msgbuf sendBuf={988,"thank you for reach"};       msgsnd(msgId,&sendBuf,strlen(sendBuf.mtext),0);          //接收到信息后发射感谢msgctl(msgId,IPC_RMID,NULL);                             //把创建的消息队列删除释放内存return 0;
}

消息队列的控制

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int main(int argc, char const *argv[])
{//使用ftok函数获取键值key_t key;if((key = ftok(".", 100)) == -1){perror("fail to ftok");exit(1);}//使用msgget函数创建一个消息队列int msgid;if((msgid = msgget(key, IPC_CREAT | 0777)) == -1){perror("fail to msgget");exit(1);}printf("msgid = %d\n", msgid);system("ipcs -q");//通过msgctl函数删除消息队列if(msgctl(msgid, IPC_RMID, NULL) == -1){perror("fail to msgctl");exit(1);}system("ipcs -q");return 0;
}

linux进程间通讯-消息队列相关推荐

  1. RT_Thread_进程间通讯——消息队列

    1.消息队列 消息队列能够接收来自线程或中断服务例程中不固定长度的消息,并把消息缓存在自己的内存空间中. 其他线程也能够从消息队列中读取相应的消息(最先进入消息队列的消息,即先进先出原则 (FIFO) ...

  2. Linux 进程间通讯(IPC)方式 ------- 共享内存

    Linux 进程间通讯(IPC)方式有以下几种: 1->管道(pipe)和有名管道(fifo). 2->消息队列 3->共享内存 4->信号量 5->信号(signal) ...

  3. Linux 进程间通讯方式 pipe()函数

    Linux 进程间通讯方式有以下几种: 1->管道(pipe)和有名管道(fifo). 2->消息队列 3->共享内存 4->信号量 5->信号(signal) 6-&g ...

  4. linux无名管道实验代码,Linux 进程间通讯之创建无名管道和读写无名管道

    Linux进程间通讯的方式: 1. 管道(pipe)和有名管道(FIFO). 2. 信号(signal) 3. 消息队列 4. 共享内存 5. 信号量 6. 套接字(socket) 管道通讯: 无名管 ...

  5. linux进程间通讯的几种方式的特点和优缺点,和适用场合。

    http://blog.csdn.net/kakaka2011/article/details/6636661 1. 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有 ...

  6. linux命名管道进程间通信,Linux进程间通讯--命名管道

    IPC安全 前面总结了匿名管道,如今来看命名管道:因为匿名管道的一个限制就是:只能是有血缘关系的进程间才能够通讯,好比:有两个同祖先的子进程,父子进程等:为了突破这一个限制,想让没有任何关系的两个进程 ...

  7. Linux进程间通讯之消息队列

    首先有个大体的概念:http://www.xefan.com/archives/83703.html 头文件: #include <sys/ipc.h> #include <sys/ ...

  8. Linux 进程间通讯详解一

    进程间的通讯 两台主机间的进程通讯 --socket一台主机间的进程通讯 --管道(匿名管道,有名管道) --System V进程间通信(IPC)包括System V消息队列,System V信号量, ...

  9. 进程间基于消息队列的通信_Linux 进程间的通信方式

    (一)进程的概念 进程是操作系统的概念,每当我们执行一个程序时,对于操作系统来讲就是创建一个进程,在这个 过程中伴随着资源的分配和释放,可以认为进程是一个程序的一次执行过程. (二)进程间通信的概念 ...

最新文章

  1. Maya摄像机动画技能学习教程
  2. faster rcnn接口_Faster R-CNN教程
  3. ASCII与汉字编码方法
  4. 如何利用 Myflash 解析 binlog ?
  5. rust模组服如何切换标准服_送给玩模组服的萌新们
  6. Java+XML+MVC框架StrutsCX简介[转]
  7. (二)利用Java WebService调用天气预报实践
  8. coverity代码检测工具介绍_微服务测试之静态代码扫描
  9. python猜数字1001untitled_ML - Python 基础
  10. keras实例化model后,结果返回NoneType
  11. python panda3d教程_panda3d基础学习
  12. 使用tail和head读取字节流
  13. paip.invalid conversion from FormWdg* to SOCKET {aka unsigned int}
  14. BetterZip for Mac(解压缩软件)
  15. 图片下载器爬虫 ItemLoader
  16. 【亚马逊运营技巧】如何查找高价值关键词?
  17. p20华为云电脑白屏_教你一招让华为P20秒变电脑,真的很简单!
  18. 【论文阅读】7-Discovering Structural Regularity in 3D Geometry
  19. 【洛谷3043】跳楼机(最短路)
  20. windows开启远程桌面,防火墙拦截:只允许特定IP远程

热门文章

  1. org.apache.tomcat.util.bcel.classfile.ClassFormatException: Invalid byte tag in constant pool: 19
  2. 欧几里德结构数据与 非欧几里德结构数据
  3. NLP(4) | 用词向量技术简单分析红楼梦人物关系用n-gramma生成词向量word2vect进行模型训练
  4. 用python编写脚本实现备份文件
  5. linux命令rname,linux的rename命令
  6. sangerbox平台使用(二)差异分析
  7. python异常处理语句编程题_一篇文章让你掌握Python异常处理所有知识点,记得收藏...
  8. 微生态、生信和植物领域最新资讯合集,不看你就亏大啦!!!
  9. JGG | 肠道细菌加重小分子量卡拉胶诱发的直肠炎症
  10. MPB:中科院生态环境中心邓晔组-环境样本中原核生物的总量测定