C语言进程间通信(三)——消息队列

消息队列是最具有数据操作性的数据传输方式,在消息队列中可随意根据特定的数据类型检索消息,随内核持续的

消息队列是一个消息的链表,每个消息队列都有个队列头,用结构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

猜你喜欢

转载自ciaos.iteye.com/blog/1860142