系统编程_消息队列

1.创建消息队列

  demo_3.c
  1 #include <sys/types.h>
  2 #include <sys/ipc.h>
  3 #include <sys/msg.h>
  4 #include <stdio.h>
  5 
  6 #if 0
  7 int msgget(key_t key, int msgflg);
  8 功能:如果键值对应的消息队列不存在,根据第二参数的权限创建消息队列,返回消息队列的标识符
  9       如果键值对应的消息队列存在,直接返回消息队列的标识符
 10 参数:
 11       key: 键值
 12       msgflg: 设置标志,IPC_CREAT|0777
 13 返回值:成功返回消息队列的标识符,出错返回-1
 14 #endif
 15 
 16 int main()
 17 {
 18     int msg_id;
 19 
 20     msg_id = msgget(0x100, IPC_CREAT | 0777);
 21     if (msg_id < 0)
 22     {
 23         perror("msgget");
 24         return -1;
 25     }
 26 
 27     printf("消息队列创建成功!\n");
 28     return 0;
 29 }


通过int msgget(key_t key, int msgflg)函数创建消息队列,成功返回消息队列的标识符,出错返回-1;

运行demo_3.c可以看到消息队列创建成功,用ipcs指令也可查看;

2.发送消息

  demo_4.c
  1 #include <sys/types.h>
  2 #include <sys/ipc.h>
  3 #include <sys/msg.h>
  4 #include <stdio.h>
  5 #include <string.h>
  6 
  7 #if 0
  8 int msgget(key_t key, int msgflg);
  9 功能:如果键值对应的消息队列不存在,根据第二参数的权限创建消息队列,返回消息队列的标识符
 10       如果键值对应的消息队列存在,直接返回消息队列的标识符
 11 参数:
 12       key: 键值
 13       msgflg: 设置标志,IPC_CREAT|0777
 14 返回值:成功返回消息队列的标识符,出错返回-1
 15 
 16 
 17 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
 18 功能:向消息队列中发送消息
 19 参数:
 20       msqid:消息队列的标识符
 21       msgp:传入参数,打包消息基本信息内存的起始地址
 22       msgsz:消息内容的大小
 23       msgflg:设置阻塞标志,0表示阻塞,IPC_NOWAIT表示非阻塞
 24 返回值:成功返回,出错返回-1
 25 
 26 打包消息信息的结构体格式如下:
 27 struct msgbuf {
 28     long mtype;   /*message type, must be > 0*/
 29     char mtext[1];   /*message data*/
 30 };
 31 #endif
 32 
 33 struct msgbuf {
 34     long mtype;
 35     char mtext[1024];
 36 };
 37 
 38 int main()
 39 {
 40     int msg_id;
 41 
 42     msg_id = msgget(0x100, IPC_CREAT | 0777);
 43     if (msg_id < 0)
 44     {
 45         perror("msgget");
 46         return -1;
 47     }
 48 
 49     printf("消息队列创建成功!\n");
 50 
 51     int ret;
 52     struct msgbuf mb = {5, "hello"};
 53     ret = msgsnd(msg_id, &mb, strlen(mb.mtext), 0);
 54     if (ret < 0) {
 55         perror("msgsnd");
 56         return -1;
 57     }
 58     printf("消息发送成功!\n");
 59 
 60     return 0;
 61 }

通过int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg)函数向消息队列中发送消息;

消息类型是5,消息内容是“hello”;

运行demo_4.c可以看到消息发送成功,用ipcs可以看到发过去1条消息,字节数为5;

往里面又写了一条重复的,然后写了一条“xiao lan”;所以消息队列里有:两个hello,一个xiao lan;

3.接受消息

  demo_5.c
  1 #include <sys/types.h>
  2 #include <sys/ipc.h>
  3 #include <sys/msg.h>
  4 #include <stdio.h>
  5 #include <string.h>
  6 
  7 #if 0
  8 int msgget(key_t key, int msgflg);
  9 功能:如果键值对应的消息队列不存在,根据第二参数的权限创建消息队列,返回消息队列的标识符
 10 如果键值对应的消息队列存在,直接返回消息队列的标识符
 11 参数:
 12 key: 键值
 13 msgflg: 设置标志,IPC_CREAT|0777
 14 返回值:成功返回消息队列的标识符,出错返回-1
 15 
 16 
 17 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
 18 功能:向消息队列中发送消息
 19 参数:
 20 msqid:消息队列的标识符
 21 msgp:传入参数,打包消息基本信息内存的起始地址
 22 msgsz:消息内容的大小
 23 msgflg:设置阻塞标志,0表示阻塞,IPC_NOWAIT表示非阻塞
 24 返回值:成功返回,出错返回-1
 25 
 26 打包消息信息的结构体格式如下:
 27 struct msgbuf {
 28     long mtype;   /*message type, must be > 0*/
 29     char mtext[1];   /*message data*/
 30 };
 31 
 32 
 33 ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
 34 
 35 功能:从消息队列中读取消息
 36 参数:
 37 msqid:消息队列的标识符
 38 msgp:传出参数,返回消息的基本信息
 39 msgsz:消息内容的大小
 40 msgtyp:指定消息的类型
 41 0:默认读取第一个消息
 42 >0:从队头开始,读取第一个指定类型的消息
 43 msgflg:设置阻塞标志
 44 0:表示阻塞
 45 IPC_NOWAIT:表示非阻塞
 46 返回值:成功返回实际读到的字节数,出错返回-1。
 47 #endif
 48 
 49 struct msgbuf {
 50     long mtype;
 51     char mtext[1024];
 52 };
 53 
 54 int main()
 55 {
 56     int msg_id;
 57 
 58     msg_id = msgget(0x100, IPC_CREAT | 0777);
 59     if (msg_id < 0)
 60     {
 61         perror("msgget");
 62         return -1;
 63     }
 64 
 65     printf("消息队列创建成功!\n");
 66 
 67     int ret;
 68     struct msgbuf mb;
 69     ret = msgrcv(msg_id, &mb, 1024, 0, 0);
 70     if (ret < 0) {
 71         perror("msgrcv");
 72         return -1;
 73     }
 74 
 75     mb.mtext[ret] = '\0';
 76     printf("recv msg: %ld|%s\n", mb.mtype, mb.mtext);
 77 
 78     return 0;
 79 }

通过ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)函数从消息队列中读取消息;

第四个参数为0是默认读第一条消息;

运行demo_5.c,读出来一条“hello”,同时用ipcs可以看到消息队列被读走一条消息;

我之前写了一个消息类型2的“xiao lan”;

demo_5.c里改成读消息类型为2的;

运行demo_5.c,消息类型2的“xiao lan”被读出来了;

  demo_6.c
  1 #include <sys/types.h>
  2 #include <sys/ipc.h>
  3 #include <sys/msg.h>
  4 #include <stdio.h>
  5 
  6 #if 0
  7 int msgget(key_t key, int msgflg);
  8 功能:如果键值对应的消息队列不存在,根据第二参数的权限创建消息队列,返回消息队列的标识符
  9       如果键值对应的消息队列存在,直接返回消息队列的标识符
 10 参数:
 11       key: 键值
 12       msgflg: 设置标志,IPC_CREAT|0777
 13 返回值:成功返回消息队列的标识符,出错返回-1
 14 #endif
 15 
 16 int main()
 17 {
 18     int msg_id;
 19 
 20     msg_id = msgget(0x100, IPC_CREAT | 0777);
 21     if (msg_id < 0)
 22     {
 23         perror("msgget");
 24         return -1;
 25     }
 26 
 27     printf("消息队列创建成功!\n");
 28 
 29     msgctl(msg_id, IPC_RMID, NULL);
 30 
 31     return 0;
 32 }

msgctl(msg_id, IPC_RMID, NULL);这个函数主要用来删除队列;

运行demo_6.c后,消息队列消息都被清空了;

也可以使用ipcrm -Q 键值来清空。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值