消息队列函数原型

在建立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 消息队列的更多相关文章

  1. linux IPC 消息队列(二)

    我在网上想找多进程之间的通信方式,发现有人写的消息队列很好,搬过来: common.h #ifndef __COMMON_H_ #define __COMMON_H_ #include <std ...

  2. IPC——消息队列

    Linux进程间通信——使用消息队列 下面来说说如何用不用消息队列来进行进程间的通信,消息队列与命名管道有很多相似之处.有关命名管道的更多内容可以参阅我的另一篇文章:Linux进程间通信——使用命名管 ...

  3. 详解linux进程间通信-消息队列

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

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

    四.消息队列(Message Queue) 消息队列就是消息的一个链表,它允许一个或者多个进程向它写消息,一个或多个进程向它读消息.Linux维护了一个消息队列向量表:msgque,来表示系统中所有的 ...

  5. linux进程间通信-消息队列

    一 消息队列的介绍 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法. 每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构. 我们可以通过发送消息来避免命名管道的 ...

  6. Linux进程间通信-消息队列(mqueue)

    前面两篇文章分解介绍了匿名管道和命名管道方式的进程间通信,本文将介绍Linux消息队列(posix)的通信机制和特点. 1.消息队列 消息队列的实现分为两种,一种为System V的消息队列,一种是P ...

  7. linux 下消息队列发送后没有信息

    在使用消息队列时,调用 #include <stdio.h> #include <stdlib.h> #include <string.h> #include &l ...

  8. linux中消息队列<一>

    1 概念 (1)链表式结构组织,存放于内核. (2)通过队列标识来引用. (3)通过一个消息类型来索引指定的数据 2 创建消息队列 #include <sys/msg.h> int msg ...

  9. linux进程间通信消息队列:msgsnd: Invalid argument

    今天写了个消息队列的小测试程序结果send端程序总是出现:msgsnd: Invalid argument,搞了半个小时也没搞明白,后来查资料发现我将(st_msg_buf.msg_type = 0; ...

随机推荐

  1. 【leetcode】662. Maximum Width of Binary Tree

    题目如下: Given a binary tree, write a function to get the maximum width of the given tree. The width of ...

  2. C/C++ C++ 11 std::move()

    { 0. C++ 标准库使用比如vector::push_back 等这类函数时,会对参数的对象进行复制,连数据也会复制.这就会造成对象内存的额外创建, 本来原意 是想把参数push_back进去就行 ...

  3. 二叉树入门(洛谷P1305)

    题目描述 输入一串完全二叉树,用遍历前序打出. 输入输出格式 输入格式: 第一行为二叉树的节点数n. 后面n行,每一个字母为节点,后两个字母分别为其左右儿子. 空节点用*表示 输出格式: 前序排列的完 ...

  4. jQuery插件之——弹窗框(模态框)leanModal

    1.首先在网上下载jquery.leanModal.min.js,添加到你的页面参考网址:https://blog.csdn.net/NTDDLIN... LeanModal.js下载地址: http ...

  5. leetcode上一些常见的链表问题

    92-按规定区间反转链表 思路:可以考虑成一种把前后数字的结点断开重新组合的问题 /** * Definition for singly-linked list. * struct ListNode ...

  6. Windows-WAMP搭建与配置

    使用 WampServer 整合软件包进行 WAMP 环境搭建 WampServer 是一款由法国人开发的 Apache Web 服务器.PHP 解释器以及 MySQL 数据库的整合软件包.免去了开发 ...

  7. IO Processing

    Types of IO IRP Buffer Management 首先区分一下page的内存与nonpaged的内存,内存如果用页管理,就难免面对被swap out的命运:但是如果用nonpaged ...

  8. 【Java多线程系列七】ExecutorService

    java.util.concurrent.ExecutorService接口提供了许多线程管理的方法 Method 说明 shutdown 拒绝接收新的任务,待已提交的任务执行后关闭,且宿主线程不阻塞 ...

  9. PHP CURL 模拟form表单上传遇到的小坑

    1:引用的时候 $parans ['img']=new \CURLFile($param); 传入的文件 在PHP版本5.5以上记得new CURLFile 不然会上传不成功 /** * http p ...

  10. [POI2010]OWC-Sheep

    题目 不难猜到或者发现的性质,如果连了一条对角线划分出了奇数个点,那么这条对角线肯定不合法:因为划分成三角形就不可能有对角线相交,于是划分成奇数的那一边怎么样也不可能划分成全是偶数 于是我们需要对每一 ...