消息队列

消息队列是消息的链式队列,模型如下:

包括两种数据结构:

msqid_ds消息队列数据结构

msg消息队列数据结构

struct msg_msg{
struct list_head m_list;
long m_type; //消息类型
int m_ts; //消息大小
struct msg_msgseg* next; //下一个消息位置
void *security; //真正消息位置
};

在/usr/include/linux/msg.h文件中定义了队列大小的限制。不同的Linux版本值不同

#define MSGMNI 16  //最大消息队列个数
#define MSGMAX 8192 //消息队列中每个消息最大为8192字节
#define MSGMNB 16384 //每个消息队列最大为16384字节

int msgget (key_t __key, int __msgflg):创建消息队列

  第一个参数:由ftok创建的key值

  第二个参数:低位确定消息队列的访问权限,最终值为perm&~umask. ??不懂

高位包含 #define IPC_CREAT  00001000    //如果key不存在,则创建,存在返回ID

#define IPC_EXCL  00002000     //如果key存在,返回失败

#define IPC_NOWAIT  00004000  //如果需要等待,直接返回错误

int msgctl (int __msqid, int __cmd, struct msqid_ds *__buf) :控制消息队列属性

  第一个参数:消息队列标识符,即msgget的返回值

  第二个参数:执行的控制命令,包括

  •     IPC_STAT 2:读取消息队列属性。取得队列的msqid_ds结构,放入第三个参数
  •     IPC_SET 1:设置消息队列属性。只有有效用户ID等于msg_perm.cuid或msg_perm.uid的进程或者超级用户特权进程可以设置。只有超级用户可以增加msg_qbytes。
  •     IPC_RMID: 删除消息队列。立即生效。仍使用这一消息队列的其他进程在下一次试图对此队列操作时,会出错返回EIDRM。同样只有两种用户可以使用该命令。
  •     IPC_INFO: 读取消息队列基本情况

  第三个参数:存储读取或需要修改的消息队列的属性

int msgsnd (int __msqid, __const void * __msgp, size_t __msgsz, int __msgflg) :发送信息到消息队列,成功返回0,否则-1.同时msg_qnum递增1,msg_lspid设置为调用进程的进程ID,msg_stime设置为当前时间。

  第一个参数:指定的消息队列标识符

  第二个参数:指向用户定义缓冲区

struct msgbuf{
long mtype; //消息类型
char mtext[]; //消息内容,在使用时自己重新定义此结构
};

  第三个参数:接收信息的大小

  第四个参数:指定达到系统限制时采取的操作。设置为IPC_NOWAIT,在需要等待时立即返回错误EAGAIN;设置为0,阻塞调用进程

int msgrcv (int __msqid, void *__msgp, size_t __msgsz, long int __msgtyp, int __msgflg) :从队列中取消息

具体说明太长了,上图:

例子,发送接收消息,读取限制信息

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<string.h>
#include<sys/msg.h>
#define BUFSIZE 128
struct msg_buf //自定义消息结构体
{
long type;
char msg[BUFSIZE];
};
int main(int argc, char *argv[])
{
key_t key;
int msgid;
struct msg_buf msg_snd, msg_rcv;
struct msginfo buf;
char *ptr = "helloworld";
memset(&msg_snd, '\0', sizeof(struct msg_buf));
memset(&msg_rcv, '\0', sizeof(struct msg_buf));
msg_rcv.type = ;
msg_snd.type = ;
memcpy(msg_snd.msg, ptr, strlen(ptr));
if((key = ftok(".",'A')) == -)
{
perror("ftok");
exit(EXIT_FAILURE);
}
if((msgid=msgget(key,|IPC_CREAT)) == -)
{
perror("msgget");
exit(EXIT_FAILURE);
}
printf("msgsnd_return = %d\n", msgsnd(msgid,(void *)&msg_snd, strlen(msg_snd.msg), ));
msgctl(msgid, MSG_INFO, &buf);
printf("buf.msgmax=%d\n", buf.msgmax);
printf("buf.msgmnb=%d\n", buf.msgmnb);
printf("buf.msgpool=%d\n", buf.msgpool);
printf("buf.semmap=%d\n", buf.msgmap);
printf("buf.msgmni=%d\n", buf.msgmni);
printf("buf.msgssz=%d\n", buf.msgssz);
printf("buf.msgtql=%d\n", buf.msgtql);
printf("buf.msgseg=%d\n", buf.msgseg); printf("msgrcv_return = %d\n", msgrcv(msgid, (void *)&msg_rcv, BUFSIZE,msg_rcv.type,));
printf("rev msg:%s\n", msg_rcv.msg);
printf("msgctl_return=%d\n",msgctl(msgid,IPC_RMID,));
}

下面是照书上抄的消息队列实现实时通信的例子

在我的电脑上无法接收消息????

send端

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<string.h>
#include<sys/msg.h>
struct msgbuf{
int type;
char ptr[];
};
int main(int argc, char *argv[])
{
key_t key;
key = ftok(argv[], );
int msgid;
msgid = msgget(key, IPC_CREAT|);
if(msgid == -)
{
perror("msgget");
exit(EXIT_FAILURE);
}
printf("key = %d, msgid = %d\n", key, msgid);
pid_t pid;
pid = fork();
if(pid == )
{
struct msgbuf data; //书上是在while循环里每次malloc,后面free 但是我那样写发现每次msgsnd都失败,说identitier removed
while()
{
printf("pls input msg to send:");
char buf[];
fgets(buf, , stdin);
data.type = ;
memcpy(data.ptr, buf, strlen(buf) + );
if(msgsnd(msgid, (void *)&data, strlen(buf) + , ) == -)
{
perror("msgsnd");
exit(EXIT_FAILURE);
}
sleep();
}
}
else
{
struct msgbuf mybuf;
while()
{
memset(&mybuf, '\0', sizeof(mybuf));
if(msgrcv(msgid, &mybuf, , , ) == -)
{
perror("msgrcv");
exit(EXIT_FAILURE);
}
printf("recv msg:%s\n", mybuf.ptr);
}
}
}

receive端代码类似,就是发送和接收的信号类型不一样。

【linux高级程序设计】(第十一章)System V进程间通信 2的更多相关文章

  1. 第三十一章 System V信号量(二)

    用信号量实现进程互斥示例 #include <unistd.h> #include <sys/types.h> #include <stdlib.h> #inclu ...

  2. 读书笔记 - js高级程序设计 - 第十一章 DOM扩展

      对DOM的两个主要的扩展 Selectors API HTML5  Element Traversal 元素遍历规范 querySelector var body = document.query ...

  3. 《JavaScript高级程序设计》——第二章在HTML使用JavaScript

    这章讲的是JavaScript在HTML中的使用,也就是<script>元素的属性.书中详细讲了async.defer.src和type四个<script>的属性. 下面是对第 ...

  4. ipc - System V 进程间通信机制

    SYNOPSIS 总览 # include <sys/types.h> # include <sys/ipc.h> # include <sys/msg.h> # ...

  5. 【linux高级程序设计】(第十一章)System V进程间通信 1

    System V, 曾经也被称为 AT&T System V,是Unix操作系统众多版本中的一支. 传统上,System V 被看作是两种UNIX"风味"之一(另一个是 B ...

  6. Linux进程通信 之 信号灯(semphore)(System V && POSIX)

    一. 信号灯简介 信号灯与其他进程间通信方式不大相同,它主要提供对进程间共享资源访问控制机制. 相当于内存中的标志,进程可以根据它判定是否能够访问某些共享资源,同时,进程 也可以修改该标志.除了用于访 ...

  7. 《Unix网络编程》卷2 读书笔记 第3章- System V IPC

    1. 概述 三种类型的System V IPC:System V 消息队列.System V 信号量.System V 共享内存区 System V IPC在访问它们的函数和内核为它们维护的信息上共享 ...

  8. 第11章 System V 信号量

    11.1 概述 信号量按功能分:二值信号量.计数信号量.信号量集:其中二值信号量和计数信号量指的是Posix信号量,信号量集指的是System V信号量.

  9. 第6章 System V消息队列

    6.1 概述 System V消息队列在内核中是list存放的,头结点中有2个指针msg_first 和msg_last.其中每个节点包含:下个节点地址的指针.类型.长度.数据等. 6.2 函数 6. ...

  10. 第3章 System V IPC

    3.1 概述 System V IPC 包含:System V消息队列.System V信号量.System V共享内存. 3.2 key_t 键和 ftok函数 这三种类型的System V IPC ...

随机推荐

  1. [bzoj3450]Tyvj1952Easy

    瓜皮期望真是弱成渣.. 完全不理解的感觉qwq...题面%了一发千古神犇WJMZBMR哈~ Description 某一天WJMZBMR在打osu~~~但是他太弱逼了,有些地方完全靠运气:(我们来简化 ...

  2. android singleTop 不起作用

    今天,排查问题,发现设置了singleTop 的activity, 多次启动依然是多个acitivity,而不是一个. 明明在清单里面设置了,但是就是启动了多个. 可能是因为启动的太快,导致系统判断有 ...

  3. 算法:枚举法---kotlin

    枚举法:效率低,循环所有的情况,找到正确答案 用于解决数学问题,还是很简单的. 比如,奥数里面: 算 法 描 述 题X题=题题题题题题 其中 算法描述题每一个为一个数字,请写出正确的数字. ok,我们 ...

  4. 世界未解之谜之----------Android Gradle

    今天运行项目,运行的debug出来的包竟然是命名过的,但是我的buildTypes里面的debug 并没有执行重命名操作.很奇怪,我的猜测是: 执行buildTypes的时候,虽然是assermdeb ...

  5. 最“高大上”的Spring测试:Spring Test

    我想给大家介绍一款非常实用.且高端大气上档次的spring测试,在这里,我要强烈推荐使用Spring的Test Context框架,为什么呢?俗话说,“货比三家不上当”,要搞清楚这个问题,我们先来看一 ...

  6. python代码简写(推导式 if else for in)

    c = a if a>b else b    //如果a>b返回a,否则返回b >>> a = 1 >>> b = 2 >>> c = ...

  7. 测试基础面试题 + SQL 面试题(选择题有部分答案,难度:低)

    测试基础面试题 + SQL 面试题(选择题有部分答案,难度:低) 答案: .A .C .C .A .A .D

  8. UIAutomator2、Appium、Robotium搭建环境与框架对比

    UIAutomator2.Appium.Robotium搭建环境与框架对比 一.框架介绍 Appium 特点 appium 是一个自动化测试开源工具,支持 iOS 平台和 Android 平台上的原生 ...

  9. 不吹不擂,你想要的Python面试都在这里了【315+道题】+精心整理的解答

    Part01-Py基础篇(80) Part02-网络编程和并发(34) Part03-数据库和缓存(46) Part04-前端框架和其他(155) Part01-Py基础篇(80) 1.为什么学习Py ...

  10. Mysql忘记root密码怎么办?(已解决)

    为了写这篇文档,假装一下忘记密码!!!! 首先我数据库是正常的,可以使用. root@localhost:~# mysql -uroot -p mysql> mysql> show dat ...