博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux 消息队列
阅读量:4876 次
发布时间:2019-06-11

本文共 3922 字,大约阅读时间需要 13 分钟。

消息队列是在两个进程间传递二进制数据的方法。每个数据块都有一个类型,接受方可以根据类型来有选择地接受数据,不需要像管道一样必须按照先进先出的顺序。

linux消息队列有四个系统调用:msgget, msgsnd, msgrcv, msgctl

msgget

#include 
#include
#include
int msgget(key_t key, int msgflg);

 

创建/获取一个消息队列。key是唯一键值,标识一个全局唯一的消息队列。msgflg指定权限

成功时返回一个正整数,是消息队列的标识符。失败返回-1,并设置errno

msgsnd

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

 

把一条消息添加到消息队列中。

msqid 是 msgget 返回的标识符。

msgp 指针指向一个准备发送的数据,必须使用这个结构体:

/* Template for struct to be used as argument for `msgsnd' and `msgrcv'.  */struct msgbuf  {    __syscall_slong_t mtype;    /* type of received/sent message */    char mtext[1];      /* text of the message */  };

 

mtype指定消息类型,必须是一个正整数。mtext是消息数据。

参数msgsz是mtext的长度,这个值可以是0,表示没有数据

参数msgflg 是控制msgsnd的行为。通常设置为 IPC_NOWAIT ,即是以非阻塞的方式发送消息。默认情况下,如果发送消息时,消息队列满了,则 msgsnd 将阻塞。如果 IPC_NOWAIT 被设置,则 msgsnd 将立刻返回并设置 erno 为 EAGAIN.

成功时返回0,失败返回-1,并设置errno

msgrcv

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

从消息队列中获取消息。

msgp 是 struct msgbuf类型的指针,msgsz 指定消息数据部分的长度

msgtyp 指定接受哪种类型的消息:

msgtyp 定于0, 读取消息队列中第一个消息

msgtyp 大于0, 读取消息队列中第一个类型为msgtyp的消息

msgtyp 小于0, 读取消息队列中第一个类型值比msgtyp的绝对值小的消息。

参数msgflg 控制msgrcv的行为。可取下列值按位或运算:

IPC_NOWAIT。如果消息队列没有消息,则 msgrcv 调用立即返回并设置errno 为 ENOMSG

MSG_EXCEPT. 如果msgtyp大于0, 接受消息队列中第一个不是msgtyp类型的消息

MSG_NOERROR。如果消息数据部分长度超过了 msgsz,将它截断。

函数成功时,返回接受的mtext长度。失败返回-1,并设置errno

msgctl

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

  设置消息队列的属性。

struct msqid_ds 结构体定义为:

/* Obsolete, used only for backwards compatibility and libc5 compiles */struct msqid_ds {    struct ipc_perm msg_perm;    struct msg *msg_first;      /* first message on queue,unused  */    struct msg *msg_last;       /* last message in queue,unused */    __kernel_time_t msg_stime;  /* last msgsnd time */    __kernel_time_t msg_rtime;  /* last msgrcv time */    __kernel_time_t msg_ctime;  /* last change time */    unsigned long  msg_lcbytes; /* Reuse junk fields for 32 bit */    unsigned long  msg_lqbytes; /* ditto */    unsigned short msg_cbytes;  /* current number of bytes on queue */    unsigned short msg_qnum;    /* number of messages in queue */    unsigned short msg_qbytes;  /* max number of bytes on queue */    __kernel_ipc_pid_t msg_lspid;   /* pid of last msgsnd */    __kernel_ipc_pid_t msg_lrpid;   /* last receive pid */};

 

msqid 是消息队列标识符。cmd 指定要执行的命令,其中

IPC_STAT.将消息队列关联的内核数据结构复制到 buf 中

IPC_RMID.立即删除消息队列标识符。唤醒所有等待读消息和写消息的进程(这些调用立即返回,并设置errno为 EIDRM)

还有其他命令,这里没有全部列举

函数失败返回-1

 

#include 
#include
#include
#include
#include
#include
#include
#include
#include
struct msgbuf_{ long mtype; char mtext[64];};int main(){ int msgid = msgget(0, 0666); pid_t pid = fork(); if (pid > 0) { struct msgbuf_ bufsnd = { 8, "send data type 8"}; if (-1 == msgsnd(msgid, &bufsnd, strlen(bufsnd.mtext), 0)) { fprintf(stderr, "msgsnd: %d, %s\n", errno, strerror(errno)); exit(1); } bufsnd.mtype = 9; strcpy(bufsnd.mtext, "this type is 9"); if (-1 == msgsnd(msgid, &bufsnd, strlen(bufsnd.mtext), 0)) { fprintf(stderr, "msgsnd: %d, %s\n", errno, strerror(errno)); exit(1); } waitpid(pid, NULL, 0); if (-1 == msgctl(msgid, IPC_RMID, NULL)) { fprintf(stderr, "msgctl: %d, %s\n", errno, strerror(errno)); exit(1); } } else if (0 == pid) { struct msgbuf_ bufrcv; int lenrcv = msgrcv(msgid, &bufrcv, 64, 9, 0); if (lenrcv < 0) { fprintf(stderr, "msgrcv: %d, %s\n", errno, strerror(errno)); exit(1); } printf("recv len=%d, type=%ld: %s\n", lenrcv, bufrcv.mtype, bufrcv.mtext); memset(&bufrcv, 0, sizeof(bufrcv)); lenrcv = msgrcv(msgid, &bufrcv, 64, 8, 0); if (lenrcv < 0) { fprintf(stderr, "msgrcv: %d, %s\n", errno, strerror(errno)); exit(1); } printf("recv len=%d, type=%ld: %s\n", lenrcv, bufrcv.mtype, bufrcv.mtext); } return 0;}

 

转载于:https://www.cnblogs.com/zuofaqi/p/9651345.html

你可能感兴趣的文章
Python:一篇文章掌握Numpy的基本用法
查看>>
序列化与ArrayList 的elementData的修饰关键字transient
查看>>
理解理解python中的'*','*args','**','**kwargs'
查看>>
php中的闭包类
查看>>
SSH登陆错误 WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
查看>>
ExtJs之Ajax模式的表单数据加载
查看>>
在javascript中获取一个对象内属性的个数
查看>>
数据结构_Python语言描述(英)pdf
查看>>
HTML5权威指南----读书笔记
查看>>
Swig--模板引擎
查看>>
OpenCV中Camshitf算法学习(补充)
查看>>
java基础面试题常出现(一)
查看>>
C# 中奇妙的函数–5. Nullable 静态类
查看>>
Windows 程序 HelloWorld
查看>>
1.1 Python是一种什么样的语言
查看>>
Spring Boot (十):邮件服务
查看>>
angular4 使用window事件【转】
查看>>
cJSON使用
查看>>
读书笔记:《C#与.NET4高级程序设计》-核心部分
查看>>
HDU 2100 LoveKey
查看>>