当前位置: 首页 > news >正文

Linux多进程_消息通信_设计思想交流(转)

Linux进程间通信可以采用的方法很多,例如“管道”、“信号”、“共享内存”、“消息队列”、“套接字”等等。不过,我个人比较喜欢“消息队列”。

        消息队列和管道相比,至少有以下几个特点:

        (1)消息队列是双向、双工的。

        (2)如果进程数量较多,要互相通信,如果采用管道的话,要创建很多个管道文件。

        (3)消息队列先天就是“异步”操作,例如A进程丢进去,B进程再读出来。A丢进去后,A还可以做其他事。不用管B什么时候去读。

             

例如:

 

消息发送函数

    int SendMSG(int mqid,long mtype,std::string _msg)
   {
        struct UMMessage msg;

        strcpy(msg.mtext,_msg.data());

        msg.mtype=mtype;

        msgsnd(mqid,&msg,strlen(msg.mtext)+1,0);

        return 1;
}

 

       (4)消息的读取操作是阻塞方式的,在多线程编程里,相当的省事

例如:

     我们启用一个专门的线程来接收消息

   void *pthread_MsgHandle(void *arg) {
       int mqid = *((int *) arg);
      struct UMMessage msg;
      while (1) {
             //接收消息,根据 KB_MSG 过滤
             int ret = msgrcv(mqid, &msg, MSG_TXT_LEN, KB_MSG, 0);
             if (ret > 0) {
                   //处理消息
                    MessageProcessing(mqid, msg.mtext);
             }
       }

      return (void*) (1);
}

 

 

  那么现在进入正题,谈谈需求。 假设现在有6个进程,相互之间要互相通信。

  进程名称依次是:A、B、C、D、E、F

 例如:A要发送消息给B、C、D

            B要发送消息给D、E、F、A

           C要发送消息给D、E、F

 

          。。。。。等等。。。。 可能性实在太多。。。

 

我们现在用消息队列就是要解决这个问题。

问题看上去很难,实际上只要好好思考,就发现用消息队列很简单。

怎么思考呢?

   首先,要创建一个消息队列。

          

 然后做好消息接收【通道】定义。

例如:

      #define CH_A      1

      #define CH_B      2

      #define CH_C      3

      #define CH_D      4

      #define CH_E       5

      #define CH_F       6

总之你有多少个进程要共用这个消息队列,你就定义多少个。

【通道】:

         解释哈,这个名词不是Linux的标准解释,仅仅是我自己规定的,就像在高速公路的车行道里规定的车道1(行车道)、车道2(货车道)、车道3(超车道)的概念。

 

通道定义好了,那么再定义消息的来源标示

例如:

     #define MSG_A   1

     #define MSG_B   2

     #define MSG_C   3

     #define MSG_D   4

     #define MSG_E   5

     #define MSG_F   6

有同学问我,为什么不直接采用通道标示呢? 原因很简单。

在一个通道里可能有很多进程发来的消息。 我们拿什么识别呢? 就用消息头识别。

 

这些定义都有了,我们再看看Linux消息的结构体定义。

struct UMMessage{
  long mtype;
  char mtext[MSG_TXT_LEN];
};

 

这些都定义完了,就来说说,怎么收发消息了。

 

首先:如果A要消息给B,则这么做。

   

       在发送消息时,指定好【通道】名称,即UM_MSG了

       在消息的内容里,加上我们事先规定好的【消息来源标示】

             例如: MSG_A={你好吗?}

     那么,A发给B的消息就是

              SendMSG(mqid,CH_B,"  MSG_A={你好吗?} " ;

               C发给B的消息就是

              SendMSG(mqid,CH_B," MSG_C={你好吗?} " ;

 

那么B怎么处理消息呢?

    首先B会根据【消息通道】号从消息队列中读取自己的【消息】

      

   然后再根据消息内容的【源标示】就可以识别消息是谁发的了。

        最后再根据 msg.mtext里面的内容的 前面部分 MSG_C 这个部分来识别是谁发的了。

 

   多个进程的消息通信基本就可以采用这个思路。如果还有疑问,欢迎大家一起来交流。

 

来源:http://blog.csdn.net/jsjjob_com/article/details/7311948

转载于:https://www.cnblogs.com/jsjjob/archive/2012/03/02/2377032.html

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 第一章:第二课 选择器-结构性伪类选择器[五]
  • nyoj 16 - 矩形嵌套
  • Excel导入导出
  • 基础常用JS
  • 记载公共语言运行库
  • 一篇关于WPF“样式”介绍的好文
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • TCP编程
  • 在线客服 qq,msn,skype, outlook 链接
  • 惠普前CEO卡莉讲演:千万不要贩卖你的灵魂(转载)
  • .net中应用SQL缓存(实例使用)
  • js函数集合大全
  • 用vs命令提示符来使用 Installutil.exe来安装和卸载Windows服务
  • 通用权限管理系统组件 (GPM - General Permissions Manager) 中实现按部门组织机构设置权限...
  • [转载]最简单的.NET生成随机数
  • 网络传输文件的问题
  • [译]Python中的类属性与实例属性的区别
  • “Material Design”设计规范在 ComponentOne For WinForm 的全新尝试!
  • 【162天】黑马程序员27天视频学习笔记【Day02-上】
  • 0基础学习移动端适配
  • CSS魔法堂:Absolute Positioning就这个样
  • echarts花样作死的坑
  • Essential Studio for ASP.NET Web Forms 2017 v2,新增自定义树形网格工具栏
  • Git同步原始仓库到Fork仓库中
  • HTTP 简介
  • java 多线程基础, 我觉得还是有必要看看的
  • Javascripit类型转换比较那点事儿,双等号(==)
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • node 版本过低
  • PHP 7 修改了什么呢 -- 2
  • Sequelize 中文文档 v4 - Getting started - 入门
  • SpiderData 2019年2月25日 DApp数据排行榜
  • 阿里云Kubernetes容器服务上体验Knative
  • 测试开发系类之接口自动化测试
  • 当SetTimeout遇到了字符串
  • 仿天猫超市收藏抛物线动画工具库
  • 服务器之间,相同帐号,实现免密钥登录
  • 给第三方使用接口的 URL 签名实现
  • 关于for循环的简单归纳
  • 面试题:给你个id,去拿到name,多叉树遍历
  • 前端js -- this指向总结。
  • 如何优雅地使用 Sublime Text
  • 一起参Ember.js讨论、问答社区。
  • 追踪解析 FutureTask 源码
  • 06-01 点餐小程序前台界面搭建
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • ​一帧图像的Android之旅 :应用的首个绘制请求
  • ​字​节​一​面​
  • #QT 笔记一
  • $().each和$.each的区别
  • (1)STL算法之遍历容器
  • (23)Linux的软硬连接
  • (第二周)效能测试
  • (二)linux使用docker容器运行mysql
  • (附源码)springboot优课在线教学系统 毕业设计 081251