Linux 消息队列

1、系统建立IPC通讯(如消息队列、共享内存等) 必须指定一个ID值。通常情况下,该id值通过ftok函数得到。

ftok原型如下:

#include  
 #include 

 key_t ftok(const char *pathname, int proj_id);

 	pathname参数:  必须是一个已经存在且程序可范围的文件。

 	proj_id参数: 虽然定义为一个整数,其实实际只有8个bit位有效,即如果该参数大于255,则只有后8bit有效。 

函数作用: convert a pathname and a project identifier to a System V IPC key, Key可用于msgget, semget, or shmget的key参数

2、消息队列

消息队列的本质是消息的链表,存放在内核中。一个消息队列由一个标识符(即队列ID)来标识。
接收进程可以独立地接收含有不同类型的数据结构。

int msgget(key_t key, int msgflg); 
	# 创建消息队列 , 返回值为该队列号
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
发送消息
	# ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
接受信息,msgtyp需要指明接受的数据type
key_t ftok(const char *pathname, int proj_id);
	# 为队列随机附加key,pathename为路径,id号可随意(1-255int msgctl(int msqid, int cmd, struct msqid_ds *buf);  # 可用于消除内内核中的队列

例子:

//发送及接受数据程序
#include
#include 
#include 
#include 
#include

#define _PATH_  "/dev/null"
#define _PROJ_ID  0x77

 struct msgbuf {
		long mtype;       /* message type, must be > 0 */
        char mtext[128];    /* message data */
 };
int main()
{
    
    struct msgbuf snddata={888,"hello rcv,this is snd"};
	struct msgbuf readdata;
	key_t key;
	key = ftok(_PATH_, _PROJ_ID);
	int msgid = msgget(key,IPC_CREAT|0777);
	printf("the key is %x\n",key);
	if(msgid == -1)
	{
		printf("creat fail\n");
	}
	else
	{
			msgsnd(msgid,&snddata,strlen(snddata.mtext),0);
			msgrcv(msgid,&readdata,sizeof(readdata.mtext),988,0);
			printf("the data come form read:%s\n",readdata.mtext);
	}
	msgctl(msgid,IPC_RMID,NULL);//销毁msgid为标识符的消息队列
		return 0;
}


//接受及发送数据程序
#include
#include 
#include 
#include 
#include

#define _PATH_  "/dev/null"
#define _PROJ_ID  0x77

 struct msgbuf {
		long mtype;       /* message type, must be > 0 */
        char mtext[128];    /* message data */
 };
int main()
{
    
	struct msgbuf snddata={988,"the data come from rcv"};
	struct msgbuf readdata;
	
	key_t key;
	key=ftok(_PATH_, _PROJ_ID);
	int msgid = msgget(key,IPC_CREAT|0777);
	printf("the key is %x\n",key);
	if(msgid ==-1)
    {
		printf("creat fail\n");
    }
	else
	{
			msgrcv(msgid,&readdata,sizeof(readdata.mtext),888,0);
			printf("the data come snd:%s ",readdata.mtext);
			msgsnd(msgid,&snddata,strlen(snddata.mtext),0);
	}
	msgctl(msgid,IPC_RMID,NULL);//销毁msgid为标识符的消息队列
		return 0;
}



你可能感兴趣的:(linux,系统,linux)