43.Linux 消息队列

msgget(message get)

msgctl  (message contorl)

msgsnd  (message send)      

msgrcv (message receive)

(1)msgget(创建消息队列)

所需头文件

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h> 

函数原型int msgget(key_t key,int flag); 
函数参数key:和消息队列关联的key值
flag:消息队列的访问权限
函数返回值成功:消息队列ID
失败:-1

创建一个消息队列:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <signal.h>
#include <unistd.h>
int main()
{
	int msgid;
	msgid=msgget(IPC_PRIVATE,0777);
	if(msgid<0)
	{
		printf("creat message queue failure\n");
		return -1; 
	}
	printf("creat message queue sucess msgid=%d\n",msgid);
	system("ipcs -q");
	return 0;
}

执行结果如下:

 key值为0,因为是通过IPC_PRIVATE的值来创建的。

(2)msgctl

所需头文件

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

函数原型int msgctl(int msgqid,int cmd,struct msqid_ds *buf);
函数参数msgqid:消息队列的队列ID
cmdIPC_STAT:读取消息队列的属性,并将其保存在buf指向的缓冲区中
IPC_SET:设置消息队列的属性。这个值取自buf参数
IPC_RMID:从系统中删除消息队列
buf:消息队列缓冲区
函数返回值成功:0
失败:-1

 

msgctl函数的使用例程

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <signal.h>
#include <unistd.h>
int main()
{
	int msgid;
	msgid=msgget(IPC_PRIVATE,0777);
	if(msgid<0)
	{
		printf("creat message queue failure\n");
		return -1; 
	}
	printf("creat message queue sucess msgid=%d\n",msgid);
	system("ipcs -q");

	//delete message queue
	msgctl(msgid,IPC_RMID,NULL);	
	system("ipcs -q");
	return 0;
}

 执行结果如下:

(3)msgsnd函数

所需头文件

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

函数原型int msgsnd(int msqid,const void *msgp,size_t size,int flag);
函数参数msqid:消息队列id

msgp:指向消息的指针。常用消息结构msgbuf如下:

struct msgbuf

{

        long mtype;    //消息类型

        char mtext[N]; //消息正文

};

size:发送消息正文的字节数

flag:IPC_NOWAIT 消息没有发送完成函数也会立即返回。(非阻塞)

        0:直到发送完成函数才返回(阻塞

函数返回值成功:0
失败:-1

(4)msgrcv

所需头文件

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

函数原型int msgrcv(int msgid,void *msgp,size_t size,long msgtype,int flag);
函数参数msgid:消息队列的ID
msgp:接收消息的缓冲区
size:要接收的消息的字节
msgtype0:接收消息队列中第一个消息
大于0:接收消息队列中第一个类型为msgtyp的消息
小于0:接收消息队列中类型值不大于msgtyp的绝对值且类型值又最小的消息
flag0:若无消息函数会一直阻塞
IPC_NOWAIT(非阻塞):若无消息 ,进程会立即返回ENOMSG。
函数返回值成功:接收到的消息的长度
出错:-1

消息队列读完节点数据会被删除

#include <stdlib.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
struct msgbuf
{
        long type;
        char text[124];
        char ID[4];
};
int main()
{
        int msgid;
        int readret;
        struct msgbuf sendbuf,recvbuf;
        msgid=msgget(IPC_PRIVATE,0777);
        if(msgid<0)
        {
                printf("creat message queue failure\n");
                return -1;
        }
        printf("creat message queue sucess msgid=%d\n",msgid);
        system("ipcs -q");
        //init sendbuf
        sendbuf.type=100;
        printf("please input message:\n");
        fgets(sendbuf.text,124,stdin);
        //start wirte message to message queue
        msgsnd(msgid,(void *)&sendbuf,strlen(sendbuf.text),0);

        //start read message from message queue
        memset(recvbuf.text,0,124);
        readret=msgrcv(msgid,(void *)&recvbuf,124,100,0);
        printf("recv:%s",recvbuf.text);
        printf("readret=%d\n",readret);
        //second read message queue
        msgrcv(msgid,(void *)&recvbuf,124,100,0);
        printf("second read after\n");
        //delete message queue
        msgctl(msgid,IPC_RMID,NULL);
        system("ipcs -q");
        return 0;
}

 

执行结果如下:

例程:实现消息队列的双向通信

服务器程序

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
struct msgbuf
{
	long type;
	char text[124];
	char ID[4];
};
int main()
{
	int msgid;
	int readret;
	int key;
        pid_t pid;	
	struct msgbuf sendbuf,recvbuf;
	key=ftok("./b.c",'a');
	if(key<0)
	{
		printf("creat key failure\n");
	}

	msgid=msgget(key,IPC_CREAT|0777);
	if(msgid<0)
	{
		printf("creat message queue failure\n");
		return -1; 
	}
	printf("creat message queue sucess msgid=%d\n",msgid);
	system("ipcs -q");
	pid=fork();
	if(pid>0)//father process write 100
	{	 	
		sendbuf.type=100;
		//WRITE MESSAGE QUEUE 
		while(1)
		{
			memset(sendbuf.text,0,124);
			printf("please input message:\n");
			fgets(sendbuf.text,124,stdin);
			msgsnd(msgid,(void *)&sendbuf,strlen(sendbuf.text),0);	
		}
	}
	if(pid==0)//son process
	{
		while(1)
		{
			memset(recvbuf.text,0,124);
			msgrcv(msgid,(void *)&recvbuf,124,200,0);
			printf("receive message form message queue:%s\n",recvbuf.text);
		}
	}

	msgctl(msgid,IPC_RMID,NULL);	
	system("ipcs -q");
	return 0;
}

客户端程序

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
struct msgbuf
{
	long type;
	char text[124];
	char ID[4];
};
int main()
{
	int msgid;
	int readret;
	int key;
        pid_t pid;	
	struct msgbuf sendbuf,recvbuf;
	key=ftok("./b.c",'a');
	if(key<0)
	{
		printf("creat key failure\n");
	}

	msgid=msgget(key,IPC_CREAT|0777);
	if(msgid<0)
	{
		printf("creat message queue failure\n");
		return -1; 
	}
	printf("creat message queue sucess msgid=%d\n",msgid);
	system("ipcs -q");
	pid=fork();
	if(pid==0)//son process write 100
	{	 	
		sendbuf.type=200;
		//WRITE MESSAGE QUEUE 
		while(1)
		{
			memset(sendbuf.text,0,124);
			printf("please input message:\n");
			fgets(sendbuf.text,124,stdin);
			msgsnd(msgid,(void *)&sendbuf,strlen(sendbuf.text),0);	
		}
	}
	if(pid>0)//father process read 100
	{
		while(1)
		{
			memset(recvbuf.text,0,124);
			msgrcv(msgid,(void *)&recvbuf,124,100,0);
			printf("receive message form message queue:%s\n",recvbuf.text);
		}
	}

	msgctl(msgid,IPC_RMID,NULL);	
	system("ipcs -q");
	return 0;
}

执行结果如下:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值