linux IPC 消息队列
消息队列函数原型
在建立IPC通讯时(如消息队列,共享内存)必须建立一个ID值。通常情况下,这个ID值由ftok函数得到
#inlcude <sys/types.h>
#include <sys/ipc.h> key_t ftok(const char *pathname, int proj_id);
返回值:成功返回键值,失败-1。
pathname:现有文件路径
proj_id:低8位整型
假如要确保key_t值不变,要目确保ftok的文档不被删除 ,要么不用ftok,指定一个固定的key_t值。
在linux下通过ftok()产生ipc键值、且ftok()与配置文件相关,则在更改了配置文件后必须将应用重起。否则将导致不可预料的后果!
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h> int main()
{
printf("key=%0x\n", ftok("aaa.txt", ));
return ;
}
ftok
打开一个现有队列或创建一个新队列:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h> int msgget(key_t key, int msgflg);
返回值:成功消息队列ID,失败-1
key:函数ftok返回值或IPC_PRIVATE(适合用在有亲缘关系的进程中)
msgflg: 消息队列的简历标志和存取权限
IPC_CREAT如果内核中没有此队列,则创建它。
IPC_EXCL当和IPC_CREAT一起使用时,如果队列已经存在,则失败。
如果单独使用IPC_CREAT,则msgget()要么返回一个新创建的消息队列的标识符,要么返回具有相同关键字值的队列的标识符。如果IPC_EXCL和IPC_CREAT一起使用,则msgget()要么创建一个新的消息队列,要么如果队列已经存在则返回一个失败值-。IPC_EXCL单独使用是没有用处的。 返回说明:
成功执行时,返回消息队列标识值。失败返回-,errno被设为以下的某个值 ,有时也会返回0,这个时候也是可以正常使用的
EACCES:指定的消息队列已存在,但调用进程没有权限访问它,而且不拥有CAP_IPC_OWNER权能
EEXIST:key指定的消息队列已存在,而msgflg中同时指定IPC_CREAT和IPC_EXCL标志
ENOENT:key指定的消息队列不存在同时msgflg中不指定IPC_CREAT标志
ENOMEM:需要建立消息队列,但内存不足
ENOSPC:需要建立消息队列,但已达到系统的最大消息队列容量
msgflg参数
对队列执行多种操作。他和另外两个与信号量及共享存储有关的函数(semctl和shmctl)都是类似于ioctl的函数(亦即垃圾桶函数)。
#include <sys/msg.h> int msgctl(int msqid, int cmd, struct msqid_ds *buf);
返回值:成功:0,失败-1
msqid:消息队列对象的标识符
cmd:消息队列进行操作
IPC_STAT:取此队列的msqid_ds结构,并将它存放在buf中
IPC_SET:将字段msg_perm.uid、msg_perm.gid、msg_perm.mode和msg_bytes从buf指向的结构复制到,与这个队列相关的msqid_ds结构中。
此命令只能由下列两种进程执行:一种是其有效用户ID等于msg_perm.cuid或msg_perm.uid,另一种是具有超级用户特权的进程。
只有超级用户才能增加msg_qbytes的值。
IPC_EMID:从系统中删除该消息队列以及仍在该队列中的所有数据。这种删除立即生效。仍在使用这一消息队列的其他进程在它们下一次试图对此队列进行操作时,将得到错误。
此命令只能由下列两种进程执行:一种是其有效用户ID等于msg_perm.cui或msg_perm.uid;另一种是具有超级用户特权的进程。
buf:缓存msqid_ds结构
struct msqid_ds {
struct ipc_perm msg_perm; /* Ownership and permissions */
time_t msg_stime; /* Time of last msgsnd(2) */
time_t msg_rtime; /* Time of last msgrcv(2) */
time_t msg_ctime; /* Time of last change */
unsigned long __msg_cbytes; /* Current number of bytes in
queue (nonstandard) */
msgqnum_t msg_qnum; /* Current number of messages
in queue */
msglen_t msg_qbytes; /* Maximum number of bytes
allowed in queue */
pid_t msg_lspid; /* PID of last msgsnd(2) */
pid_t msg_lrpid; /* PID of last msgrcv(2) */
};
struct msqid_ds
其中又有ipc_perm结构:
struct ipc_perm {
key_t __key; /* Key supplied to msgget(2) */
uid_t uid; /* Effective UID of owner */
gid_t gid; /* Effective GID of owner */
uid_t cuid; /* Effective UID of creator */
gid_t cgid; /* Effective GID of creator */
unsigned short mode; /* Permissions */
unsigned short __seq; /* Sequence number */
};
struct ipc_perm
调用msgsnd将数据放到消息队列中
#include <sys/msg.h> int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
返回值:成功0,失败-1
msqid:消息队列识别码
msgp:指向消息缓冲区的指针,此位置用来暂时存储发送和接收消息,是用户定义的通用结构。
msgsz:消息的大小
msgflg: 0当消息队列满时,msgsnd会阻塞,直到消息能写进队列
IPC_NOWAIT当消息队列已满时,msgsnd函数不等待立即返回
IPC_NOERROR若发送的消息大于size字节,则把消息截断,截断部分将丢弃,且不通知发送进程
msgp结构为:
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[]; /* message data */
};
struct msgbuf
msgrcv从队列中取用消息
#include <sys/msg.h> ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
返回值:成功返回消息数据部分的长度,出错-
msqid:消息队列识别码
msgp:消息结构体,和msgsnd一样
msgsz:接收消息的大小
msgtyp: 0接收第一个消息
>0接收类型等于msgtyp的第一个消息
<0接收类型等于或小于msgtyp绝对值的第一个消息
msgflg: 0阻塞式接收消息,没有该类型的消息msgrcv函数一直阻塞等待
IPC_NOWAIT如果没有返回条件的消息调用立即返回
IPC_EXCEPT与msgtype配合使用返回队列中第一个类型不为msgtype的消息
IPC_NOERROR如果队列中满足条件的消息内容大于所请求的size字节,则把消息截断并丢弃截断部分
消息队列使用的例子:
#include <stdio.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <string.h> #define TEXT_SIZE 512 struct msgbuf {
long mtype;
char mtext[TEXT_SIZE];
}; int main(int argc, char *argv[])
{
int msqid;
pid_t pid;
struct msgbuf msg; msqid = msgget(IPC_PRIVATE, IPC_CREAT|);
if(msqid == -)
{
printf("create msg queue failed!\n");
return -;
} pid = fork();
if(pid < ) {
printf("fork failed!\n");
return -;
} else if(pid == ) { /* child */
msgrcv(msqid, &msg, sizeof(msg), , IPC_NOWAIT);
printf("child: msg.mtext is %s\n", msg.mtext);
strcpy(msg.mtext, "Hello, too!");
msgsnd(msqid, &msg, sizeof(msg), IPC_NOWAIT);
} else { /* parent */
msg.mtype = ;
strcpy(msg.mtext, "Hello!");
msgsnd(msqid, &msg, sizeof(msg), IPC_NOWAIT);
sleep();
msgrcv(msqid, &msg, sizeof(msg), , IPC_NOWAIT);
printf("parent:msg.mtext is %s\n", msg.mtext);
}
return ;
}
linux IPC 消息队列的更多相关文章
- linux IPC 消息队列(二)
我在网上想找多进程之间的通信方式,发现有人写的消息队列很好,搬过来: common.h #ifndef __COMMON_H_ #define __COMMON_H_ #include <std ...
- IPC——消息队列
Linux进程间通信——使用消息队列 下面来说说如何用不用消息队列来进行进程间的通信,消息队列与命名管道有很多相似之处.有关命名管道的更多内容可以参阅我的另一篇文章:Linux进程间通信——使用命名管 ...
- 详解linux进程间通信-消息队列
前言:前面讨论了信号.管道的进程间通信方式,接下来将讨论消息队列. 一.系统V IPC 三种系统V IPC:消息队列.信号量以及共享内存(共享存储器)之间有很多相似之处. 每个内核中的 I P C结构 ...
- Linux进程间通信—消息队列
四.消息队列(Message Queue) 消息队列就是消息的一个链表,它允许一个或者多个进程向它写消息,一个或多个进程向它读消息.Linux维护了一个消息队列向量表:msgque,来表示系统中所有的 ...
- linux进程间通信-消息队列
一 消息队列的介绍 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法. 每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构. 我们可以通过发送消息来避免命名管道的 ...
- Linux进程间通信-消息队列(mqueue)
前面两篇文章分解介绍了匿名管道和命名管道方式的进程间通信,本文将介绍Linux消息队列(posix)的通信机制和特点. 1.消息队列 消息队列的实现分为两种,一种为System V的消息队列,一种是P ...
- linux 下消息队列发送后没有信息
在使用消息队列时,调用 #include <stdio.h> #include <stdlib.h> #include <string.h> #include &l ...
- linux中消息队列<一>
1 概念 (1)链表式结构组织,存放于内核. (2)通过队列标识来引用. (3)通过一个消息类型来索引指定的数据 2 创建消息队列 #include <sys/msg.h> int msg ...
- linux进程间通信消息队列:msgsnd: Invalid argument
今天写了个消息队列的小测试程序结果send端程序总是出现:msgsnd: Invalid argument,搞了半个小时也没搞明白,后来查资料发现我将(st_msg_buf.msg_type = 0; ...
随机推荐
- Windows10 通用快捷键命令
总想着甩掉鼠标,来一种只用键盘的各种行云流水般的快捷操作,在网上各个论坛,博客,搜索引擎,最后终于记录整理了出来! 为了尝试新的命令提示符下,只需 打开开始菜单,然后键入cmd并回车. 按Ct ...
- find及其他命令
Find命令 Find / -type f :f为普通文件 Find / -name *.txt :查找.txt结尾的 Find / -size +30M :找根目录下大于30M的文件 F ...
- Spring框架-经典的案例和demo,一些可以直接用于生产,使用atomikos来处理多数据源的一致性事务等
Spring Examples Demo website:http://www.ityouknow.com/ 对Spring框架的学习,包括一些经典的案例和demo,一些可以直接用于生产. sprin ...
- mysql全家桶(二)数据操作
一.数据操作1.增#新增insert into 表名(字段列表) values(值列表);INSERT INTO table_name ( field1, field2,...fieldN ) VAL ...
- php开发面试题---Redis和Memcache区别,优缺点对比
php开发面试题---Redis和Memcache区别,优缺点对比 一.总结 一句话总结: Redis相当于Memcache的扩展,增加比如持久化.多种数据结构.集群分布式功能 反思的回顾非常有用,因 ...
- JS-jQuery:百科
ylbtech-JS-jQuery:百科 jQuery是一个快速.简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库(或JavaScript框架).jQu ...
- selenium2-java环境搭建 示例为chrome浏览器
首先,安装并配置JDK,安装eclipse,安装firefox和chrome.下载selenium语言的JAVA库文件,下载地址为,如果打不开,则需要翻墙:http://www.seleniumhq. ...
- excel数据生成sql insert语句
excel数据生成sql insert语句 excel表格中有A.B.C三列数据,希望导入到数据库users表中,对应的字段分别是name,sex,age . 在你的excel表格中增加一列,利用ex ...
- Ubuntu下实现Nginx+Tomcat实现负载均衡
先说一下为什么写这个文章,在性能测试过程中,我们可能会关注很多指标,比如CPU.IO.网络.磁盘等,通过这些指标大致可以判断哪个环节遇到了性能瓶颈,但是当这些指标无法判断出性能瓶颈时,我们可能就需要对 ...
- 高博SLAM14讲 ch5 点云拼接例程实现与bug处理
一.环境配置,基本库的安装 1.Eigen库 apt-get 安装 2.sophus库 apt-get 安装 3.pcl 点云库 (1)官方预编译版本 sudo apt-get install lib ...