消息队列是最具有数据操作性的数据传输方式,在消息队列中可随意根据特定的数据类型检索消息,随内核持续的
消息队列是一个消息的链表,每个消息队列都有个队列头,用结构struct msg_queue描述,队列头包含队列的大量消息,包括消息队列键值,用户ID,组ID,消息数目等。
struct msg_queue { struct ipc_perm q_perm; time_t q_stime; //最后一次msgsnd时间 time_t q_rtime; //最后一次msgrcv时间 time_t q_ctime; //最后一次变更时间 unsigned long q_cbytes; //当前消息队列中字节数目 unsigned long q_qnum; //队列中消息个数 unsigned long q_qbytes; //队列中最大字节数目 pid_t q_lspid; //最后msgsnd的进程ID pid_t q_lrpid; //最后receive进程ID struct list_head q_messages; struct list_head q_receivers; struct list_head q_senders; }
结构msqid_ds用来设置或返回消息队列的信息
struct msqid_ds { struct ipc_perm q_perm; struct msg *msg_first; //第一个消息 struct msg *msg_last; //最后一个消息 time_t msg_stime; //最后一次msgsnd时间 time_t msg_rtime; //最后一次msgrcv时间 time_t msg_ctime; //最后一次变更时间 pid_t msg_lspid; //最后msgsnd的进程ID pid_t msg_lrpid; //最后receive进程ID //... }
消息队列读端
//read_queue.c #include<sys/types.h> #include<sys/ipc.h> #include<sys/msg.h> #include<stdio.h> #include<sys/stat.h> #include<unistd.h> #include <errno.h> #define LEN 10 typedef struct { long int my_msg_type; char msg[LEN+1]; }msg_buf; int main() { int ret; int msg_id; msg_id = msgget((key_t)1000,0666|IPC_CREAT); if(msg_id == -1){ printf("msgget failed\n"); return -1; } printf("msg_id:%d\n",msg_id); msg_buf mb; ret = msgrcv(msg_id,(void *)&mb,sizeof(msg_buf),3,IPC_NOWAIT); if(ret == -1){ printf("msgrcv failed:%d\n",errno); return -1; } printf("recv %s\n",mb.msg); return 0; }
消息队列写端
//create_queue.c #include<sys/types.h> #include<sys/ipc.h> #include<sys/msg.h> #include<stdio.h> #include<string.h> #include<sys/stat.h> #include<unistd.h> #include<errno.h> #define LEN 10 typedef struct { long int my_msg_type; //64位机器必须设置为long char msg[LEN+1]; }msg_buf; int main() { int i; int ret; int msg_id; msg_id = msgget((key_t)1000,0666|IPC_CREAT); if(msg_id == -1){ printf("msgget failed\n"); return -1; } printf("msg_id=%d\n",msg_id); msg_buf mb; mb.my_msg_type = 3; strncpy(mb.msg,"msg1",LEN); ret = msgsnd(msg_id,(void *)&mb,sizeof(msg_buf),0); if(ret == -1){ printf("msgsnd failed\n"); return -1; } printf("message sent:%d\n",ret); return 0; }
注意针对64位机器,必须设置type为long类型,不然消息不会被接收端收到
编译运行结果如下
root:~/ciaos # ./write msg_id=327689 message sent:0 root:~/ciaos # ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages 0x000003e8 327689 root 666 24 1 root:~/ciaos # ./read msg_id:327689 recv msg1 root:~/ciaos # ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages 0x000003e8 327689 root 666 0 0