博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
进程通信之消息队列
阅读量:4298 次
发布时间:2019-05-27

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

1、消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式以及特定的优先级

2、 对消息队列有写权限的进程可以向其中按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读走消息。

3、man 2 msgrcv

4、函数int msgget(key_t key, int msgflg)

     –参数“key”:消息队列关联的标识符  key =  IPC_PRIVATV = 0 

     –参数“msgflg”:消息队列的建立标志和存取权限。IPC_CREAT 如果内核中没有此队列则创建它;IPC_EXCL 当          和IPC_CREAT 一起使用时,如果队列已经存在,则失败。
     –返回值:执行成功则返回消息队列的标识符,否则返回-1。

5、 #include <sys/types.h>

       #include <sys/ipc.h>
       #include <sys/msg.h>

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

msqid:为指定的要操作的队列
cmd:参数指定所要进行的操作,其中有些操作需要buf参数。
IPC_STAT
IPC_SET
IPC_RMID //删除消息队列

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) */};The ipc_perm structure is defined as follows (the highlighted fields are settable using IPC_SET):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 */};

6、函数ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg)

      –参数msqid:消息队列的标识码

      –参数*msgp:指向消息缓冲区的指针

      –参数msgsz:消息的长短

      参数msgtyp

             • msgtyp等于0 ,则返回队列的最早的一个消息

             • msgtyp大于0,则返回其类型为mtype的第一个消息

             • msgtyp小于0,则返回其类型小于或等于mtype参数的绝对值的最小的一个消息

      –参数msgflg:标志位为0,则表示忽略

      –返回值:成功返回数据长度,错误返回-1

7、函数int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg)

     –参数msqid:消息队列的标识码

     –参数*msgp:指向消息缓冲区的指针,此位置用来暂时存储发送和接收的消息,是一个用户可定义的通用结构

     –参数msgsz:消息的长短

     –参数msgflg:标志位

     –返回值:成功返回0,错误返回-1

结构体msgp,是一个标准的通用结构

struct msgbuf {      long mtype;       /* message type, must be > 0 */      char mtext[nbyte];    /* message data */};
例:

msgsend.c

#include 
#include
#include
#include
#include
#include
#define MAX_TEXT 512 struct msg_st { long int msg_type; char text[MAX_TEXT]; }; int main(){ int running = 1; struct msg_st data; char buffer[BUFSIZ]; int msgid = -1; //建立消息队列 msgid = msgget((key_t)1234, 0666 | IPC_CREAT); if(msgid == -1) { fprintf(stderr, "msgget failed with error: %d\n", errno); exit(EXIT_FAILURE); } //向消息队列中写消息,直到写入end while(running) { //输入数据 printf("Enter some text: "); fgets(buffer, BUFSIZ, stdin); data.msg_type = 1; //注意2 strcpy(data.text, buffer); //向队列发送数据 if(msgsnd(msgid, (void*)&data, MAX_TEXT, 0) == -1) { fprintf(stderr, "msgsnd failed\n"); exit(EXIT_FAILURE); } //输入end结束输入 if(strncmp(buffer, "end", 3) == 0) running = 0; sleep(1); } exit(EXIT_SUCCESS); }

msgreceive.c

#include 
#include
#include
#include
#include
#include
struct msg_st{ long int msg_type; char text[BUFSIZ]; }; int main() { int running = 1; int msgid = -1; struct msg_st data; long int msgtype = 0; //注意1 //建立消息队列 msgid = msgget((key_t)1234, 0666 | IPC_CREAT); if(msgid == -1) { fprintf(stderr, "msgget failed with error: %d\n", errno); exit(EXIT_FAILURE); } //从队列中获取消息,直到遇到end消息为止 while(running) { if(msgrcv(msgid, (void*)&data, BUFSIZ, msgtype, 0) == -1) { fprintf(stderr, "msgrcv failed with errno: %d\n", errno); exit(EXIT_FAILURE); } printf("You wrote: %s\n",data.text); //遇到end结束 if(strncmp(data.text, "end", 3) == 0) running = 0; } //删除消息队列 if(msgctl(msgid, IPC_RMID, 0) == -1) { fprintf(stderr, "msgctl(IPC_RMID) failed\n"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }

转载地址:http://oynws.baihongyu.com/

你可能感兴趣的文章
HTTP协议[转]
查看>>
字典序算法[转]
查看>>
emplace_back和push_back的区别[转]
查看>>
海量数据处理算法:Bloom Filter[转]
查看>>
vim常用命令
查看>>
C++ STL之map与unordered_map
查看>>
散列(hash)表算法[转]
查看>>
C++之lambda表达式
查看>>
Atom插件Markdown Preview Enhanced的字体大小修改
查看>>
C++ STL之正则表达式
查看>>
超强vim配置文件[转]
查看>>
Vim代码补全插件YouCompleteMe的自动化安装[转]
查看>>
虚函数的实调用与虚调用
查看>>
memcpy与memmove区别和实现
查看>>
DNS域名解析过程
查看>>
IP、TCP、UDP首部详解
查看>>
move和forward源码分析[转]
查看>>
智能指针之make_unique与make_shared
查看>>
使用智能指针的注意事项
查看>>
C++之失控指针、迷途指针、野指针、悬浮指针及空指针[转]
查看>>