linux 消息队列使用
来源:互联网 发布:淘宝新品期是多少天 编辑:程序博客网 时间:2024/05/12 12:40
学习API当然用man喽。
API:
#include <sys/types.h>#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
get a message queue identifier
key -- 关键字
msgflg -- 标志 IPC_CREAT 或 IPC_EXCL
一般使用msgget创建消息队列,key自定义一个,如果系统已经使用了该key值,那有可能就创建失败了。
还有创建完权限的问题,这个还没有深入研究。
return -- -1 if error and errno indicating the error.
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
发送消息
msgp -- 指向消息的结构,例如消息的结构如下
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[64]; /* message data */
};
其中 mtest 数组的大小就是 msgsz 的值。
mtype -- 消息类型,在接收时需要这个值用来区分各个消息。注意,这个取值是有讲究的。The mtype field must have a strictly positive integer value. 正数可以,负数就不行!!!
msgflg -- 标志 IPC_NOWAIT MSG_EXCEPT MSG_NOERROR 等,
return -- -1 if error and errno indicating the error.
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
接收消息
知道发送的话,接收就容易了。
int msgctl (int msqid, int cmd, struct msqid_ds *buf)
消息队列属性控制
msqid:消息队列的标识符。
cmd:执行的控制命令,即要执行的操作。(包括以下选项:
IPC_STAT:读取消息队列属性。取得此队列的msqid_ds 结构,并将其存放在buf指向的结构中。
IPC_SET :设置消息队列属性。
IPC_RMID:删除消息队列。
IPC_INFO:读取消息队列基本情况。此命令等同于 ipcs 命令。
这 4 条命令(IPC_STAT、IPC_SET、IPC_INFO 和 IPC_RMID)也可用于信号量和共享存储。)
buf:临时的 msqid_ds 结构体类型的变量。用于存储读取的消息队列属性或需要修改的消息队列属性。
举例:msgctl(qid, IPC_RMID, NULL) //删除消息队列
看了API,就可以写两个进程跑一下了。
process1
#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>#include <string.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#define MY_MSG_TYPE 0xaabbstruct msg { long msg_types; char msg_buf[3];};static key_t mykey = 0x1234;static char buf[5][3] ={ { 'a', 'b', 'c'}, { 'd', 'e', 'r'}, { 'g', 'h', 'i'}, { 'j', 'k', 'l'}, { 'm', 'n', 'o'}};int main(){ struct msg pmsg; int msgid; int i; int ret; printf("process send start\n"); i = 0; msgid = msgget(mykey, IPC_CREAT | 00666); if (msgid < 0) { printf("creat msg failed\n"); return 0; } pmsg.msg_types = MY_MSG_TYPE; while (1) { memcpy(&pmsg.msg_buf, &(buf[i][0]), 3); printf("msgid %d pmsg.msg_buf %c %c %c\n", msgid, pmsg.msg_buf[0], pmsg.msg_buf[1], pmsg.msg_buf[2]); ret = msgsnd(msgid, &pmsg, 3, IPC_NOWAIT); if (ret < 0) { switch (errno){case E2BIG:printf("<xmpp>1111消息文本长度大于msgsz,并且msgflg中没有指定MSG_NOERROR\n");break;case EACCES: printf("<xmpp>2222调用进程没有读权能,同时没具有CAP_IPC_OWNER权能\n"); break;case EAGAIN: printf("<xmpp>3333消息队列为空,并且msgflg中没有指定IPC_NOWAIT\n"); break;case EFAULT: printf("<xmpp>444msgp指向的空间不可访问\n"); break;case EIDRM: printf("<xmpp>555当进程睡眠等待接收消息时,消息队列已被删除\n"); break;case EINTR: printf("<xmpp>666当进程睡眠等待接收消息时,被信号中断\n"); break;case EINVAL: printf("<xmpp>777 inval\n"); break;case ENOMSG: printf("<xmpp>888msgflg中指定了IPC_NOWAIT,同时所请求类型的消息不存在\n"); break;default: printf("<xmpp>999其他错误\n"); break;} break; } i++; if (i >= 5) { i = 0; } sleep(3); } msgctl(msgid, IPC_RMID, NULL); return 0;}
process2
#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>#include <string.h>#include <stdio.h>#include <stdlib.h>#define MY_MSG_TYPE 0xaabbccddstruct msg { long msg_types; char msg_buf[3];};static key_t mykey = 0x1234;int main(){ struct msg pmsg; int msgid; int i; ssize_t ret; printf("process receive start\n"); printf("aaaaaaaaaaaaaaaaaa\n"); i = 0; msgid = msgget(mykey, IPC_CREAT | 00666); if (msgid < 0) { printf("GET MSG FAILE\n"); return 0; } printf("!!!!\n"); while (1) { ret = msgrcv(msgid, &pmsg, 3, MY_MSG_TYPE, 0); if (ret < 0) { printf("receive error!!!\n"); } else { printf("get message ret = %d %c %c %c\n", ret, pmsg.msg_buf[0], pmsg.msg_buf[1], pmsg.msg_buf[2]); } sleep(1); } msgctl(msgid, IPC_RMID, NULL); return 0;}
把 process2 放在后台运行,再运行 process1。
就会有打印了
.out main.c
[chenct@localhost p1]$ ./a.out
process send start
msgid 884736 pmsg.msg_buf a b c
get message ret = 3 a b c
成功。
0 0
- linux 消息队列使用
- linux 使用消息队列
- linux 消息队列使用1
- linux下消息队列使用
- linux 消息队列使用经验
- Linux消息队列的使用
- linux 共享内存消息队列使用
- linux c 消息队列的使用
- 关于linux中消息队列的使用
- Linux下的消息队列的使用
- 【Linux】Linux进程间通信——使用消息队列
- Linux消息队列编程
- linux消息队列
- linux消息队列操作
- linux IPC-消息队列
- linux消息队列函数
- Linux消息队列操作
- linux 消息队列
- 实践与理论
- Java界面 SWT基本组件——组合框(Combo)
- SIFT
- EasyUI tree实现双击展开/折叠
- BGP Link Bandwidth
- linux 消息队列使用
- java 多线程的生产者-消费者 实现
- InputFormat的数据划分、Split调度、数据读取三个问题的浅析
- 类中 为什么使用友元
- 利用monkey测试android,入门级用户可能遇见的错误及解决办法
- MentoHUST讲解教程(锐捷破解)
- 方块填数
- ARM中断向量表重定位到片外RAM方法
- 在局域网中共享打印机