消息队列是消息的连接表,存储在内核中。本实例主要实现消息队列方式进行进程间通信,接收端收到消息之后,立马转发给发送端;发送端发出消息之后,立马监听接收端回馈的消息,实现一个双向通信示例。

一、示例

发送端client.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <unistd.h>#define MSG_FILE "server.c"
#define BUFFER 255
#define PERM S_IRUSR|S_IWUSRstruct msgtype {  long mtype;  char buffer[BUFFER];
}; int main(int argc,char **argv)
{  struct msgtype msg;  key_t key;  int msgid;struct msqid_ds msqid;if((key = ftok(MSG_FILE, 'a')) == -1) {  fprintf(stderr,"Creat Key Error:%s\a\n",strerror(errno));  exit(-1);  }if((msgid = msgget(key, PERM | IPC_CREAT))==-1)  {  fprintf(stderr,"Creat Message Error:%s\a\n",strerror(errno));  exit(-1);  }printf("PID=%d\n", getpid());while(1) {printf("Please in put the sending msg:");if((fgets(msg.buffer, BUFFER, stdin)) == NULL){printf("No message, terminal msg sending\n");exit(1);}msg.mtype=1;// client send.msgsnd(msgid, &msg, sizeof(struct msgtype), 0);memset(&msg,'\0',sizeof(struct msgtype));sleep(1);// client recive.msgrcv(msgid, &msg, sizeof(struct msgtype), 2, 0);fprintf(stderr,"Client receive:[ID=%ld] msg=%s\n", msg.mtype, msg.buffer);msgctl(msgid, IPC_STAT, &msqid);printf("last-msgsnd pid=%d\nlast-msgrcv pid=%d\n", msqid.msg_lspid, msqid.msg_lrpid);}// remove msg in system and delete all data in buffer.msgctl(msgid, IPC_RMID, NULL);exit(0);
}

接收端Server.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/stat.h>
#include <sys/msg.h>  #define MSG_FILE "server.c"
#define BUFFSIZE 255
#define PERM S_IRUSR|S_IWUSR  struct msgtype {  long mtype;  char buffer[BUFFSIZE];
};int main(void) {  struct msgtype msg;  key_t key;  int msgid;  if((key = ftok(MSG_FILE, 'a')) == -1) {  fprintf(stderr,"Creat Key Error %s\a\n",strerror(errno));  exit(-1);  }if((msgid = msgget(key, PERM|IPC_CREAT)) == -1) {  fprintf(stderr,"Creat Message Error:%s\a\n",strerror(errno));  exit(-1);  }  printf("PID=%d\n", getpid());while(1){// server receive.msgrcv(msgid, &msg, sizeof(struct msgtype), 1, 0);  fprintf(stderr,"Server Receive:[ID=%ld] %s\n", msg.mtype, msg.buffer);msg.mtype = 2;// server send.printf("send:%s\n", msg.buffer);msgsnd(msgid, &msg, sizeof(struct msgtype), 0);}  exit(0);
}

运行结果:

接收端

PID=141798
Server Receive:[ID=1] hello

send:hello

Server Receive:[ID=1] hello

send:hello

Server Receive:[ID=1] world

send:world

发送端

PID=141800
Please in put the sending msg:hello
Client receive:[ID=2] msg=hello

last-msgsnd pid=141798
 last-msgrcv pid=141800
Please in put the sending msg:world
Client receive:[ID=2] msg=world

last-msgsnd pid=141798
 last-msgrcv pid=141800

二、接口函数分析

key_t ftok(const char *path, int id);

内核中IPC结构(消息队列、信号量、共享内存)都有一个唯一的非负整数标识符,都是通过ftok函数产生。Path,必须引用一个现有的文件,当产生key时,只使用id参数的低8位。

int msgget (key_t key, int msgflg);

用于创建一个新队列或者打开一个现有队列,比如指定key为IPC_PRIVATE表示引用一个现有队列;而用ftok产生的key,表示创建一个新队列。msgflg有三个:
        IPC_CREAT(如果key不存在就创建);
        IPC_EXCL(如果key存在,返回失败);
        IPC_NOWAIT(返回错误不等待)

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

msqid表示msget返回的id值;msgp指针指向发送的自定义的数据buffer;msgsz,指定发送数据buffer的长度;msgflag可以指定为IPC_NOWAIT,表示如果队列已满,立即返回EAGAIN,如果没有指定IPC_NOWAIT,则会一直阻塞到:有空间可以容纳要发送的消息,或者从系统中删除了此队列(返回EIDRM错误),或者捕捉到一个信号并从信号处理程序返回(返回EINTR错误)。

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

msqidmsgpmsgszmsgflag与上面msgsnd接口描述的一样,msgtyp指定了在msgflg指定的队列溢出或者下溢之后返回的消息值。msgtyp分类:
        msgtyp==0,返回队列中第一个消息;
        msgtyp>0,返回队列中消息类型为msgtyp的消息;
        msgtyp<0,返回队列中消息类型小于msgtyp绝对值的消息,如果消息有多个,则取类型值最小的那个。

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

类似于ioctl函数,第一个参数msqid是msgget的返回值,第二个cmd有如下:
        IPC_SATA,获取队列的msqid_ds结构体信息,并存入buf中;
        IPC_SET,讲buf中相关msqid_ds相关数据设定到队列的msqid_ds中;
        IPC_RMID,从系统中删除该消息队列以及仍然在队列中的数据,删除立即生效,如果正在使用这个队列的进程当它再一次对队列进行操作时会返回EIDRM错误;

Linux IPC 进程间通信——消息队列message相关推荐

  1. Linux的进程间通信-消息队列

    Linux的进程间通信-消息队列 微博ID:orroz 微信公众号:Linux系统技术 前言 Linux系统给我们提供了一种可以发送格式化数据流的通信手段,这就是消息队列.使用消息队列无疑在某些场景的 ...

  2. Linux进程间通信--消息队列(Message queuing)

    今天我们来谈一谈Linux进程间通信的方式之一消息队列 我们先来看看关于消息队列的定义: 1.消息队列是消息的链表,存放在内核中并由消息队列标识符表示. 2.消息队列提供了一个从一个进程向另一个进程发 ...

  3. Linux IPC POSIX 消息队列

    模型: #include<mqueue.h> #include <sys/stat.h> #include <fcntl.h> mq_open() //创建/获取消 ...

  4. 进程间通信——消息队列(Message queue)

    在Linux中,IPC消息队列是一个双向通信的全内存设计,即内核保证了读写顺序和数据同步,并且是性能比较好的先进先出的数据结构.消息队列的应用场景:比如异步任务处理,抢占式的数据分发,顺序缓存区等. ...

  5. linux 消息对lie_详解linux进程间通信-消息队列

    前言:前面讨论了信号.管道的进程间通信方式,接下来将讨论消息队列. 一.系统V IPC 三种系统V IPC:消息队列.信号量以及共享内存(共享存储器)之间有很多相似之处. 每个内核中的 I P C结构 ...

  6. Linux进程间通信——消息队列

    2019独角兽企业重金招聘Python工程师标准>>> 下面来说说如何用不用消息队列来进行进程间的通信,消息队列与命名管道有很多相似之处.有关命名管道的更多内容可以参阅我的另一篇文章 ...

  7. linux进程间通信--消息队列相关函数(ftok)详解

    ftok 消息队列.信号灯.共享内存常用在Linux服务端编程的进程间通信环境中.而此三类编程函数在实际项目中都是用System V IPC函数实现的.System V IPC函数名称和说明如下表15 ...

  8. linux 进程通信 消息队列

    详解linux进程间通信-消息队列 前言:前面讨论了信号.管道的进程间通信方式,接下来将讨论消息队列. 一.系统V IPC 三种系统V IPC:消息队列.信号量以及共享内存(共享存储器)之间有很多相似 ...

  9. Linux IPC进程间通信(三):信号量

    系列文章: Linux IPC进程间通信(一):管道 Linux IPC进程间通信(二):共享内存 Linux IPC进程间通信(三):信号量 Linux IPC进程间通信(四):消息队列 文章目录 ...

最新文章

  1. 邮件发送类,支持HTML格式,支持优先级设置
  2. BBSSDK插件技术方案
  3. WCF方法拦截及OperationInvoker传递参数到WCF方法的实现
  4. mojoportal学习——文章翻译之多行横排菜单
  5. php 中文 decode_php json_decode 解析中文
  6. 机器学习实际应用_机器学习的实际好处是什么?
  7. mysql5.7.11 创建用户_修改更新查找MySQL5.7.x的root用户的默认密码
  8. .aspx页面 引用命名空间 (Import 指令,web.config)
  9. Windows编程中引入winsock2.h后导致的错误解决
  10. Windows核心编程学习九:利用内核对象进行线程同步
  11. Vscode 调试:跟踪局部变量的变化
  12. Java开发 明华usbkey_v3 明华二次开发包,usbkey 内有很多demo程序。 USB develop 238万源代码下载- www.pudn.com...
  13. HikariCP连接池
  14. 投资理财——如何选择基金
  15. 通宵写6000字,浅谈密码的破解(破解HASH算法加密)
  16. 今天不忙,咱们来说说域名是什么意思?
  17. 利用 EXE4j 生成 .exe Java Swing程序
  18. pythonsze_python学习笔记二 数据类型(基础篇)
  19. python内置函数返回元素个数_Python内置函数
  20. 【树莓派不吃灰】基础篇⑮ SSH远程访问安全,涉及/etc/hosts.allow白名单 和 /etc/hosts.deny黑名单、ufw防火墙、密钥登录

热门文章

  1. 掌纹识别matlab,matlab掌纹识别思路
  2. 【银河麒麟V10】【桌面】数据盘设置DEF多个用户分区
  3. [统计]_通俗地讲置信区间
  4. 性能提升10倍以上:阿里达摩院成功研发新型存算一体芯片
  5. 【Python从零开始】caffe2的安装过程(在win10+Python+VS2015的环境下,改成caffe2的安装)(2)
  6. Virtualbox的centos7 Nat和桥接网络配置
  7. Windows server 2012R2下负载均衡服务器之ISCSI服务器配置
  8. S32K144(4)LED
  9. icp信息服务器,ICP
  10. keil中micro lib