進程間通信之消息隊列

一消息隊列:

1,消息隊列就是一個消息的鏈表,把消息看做一個記錄,具有特定格式。 進程可以向其中按照一定的規則添加新消息;另一些進程則可以從消息隊列中讀走消息。

2,分類:POSI消息隊列,系統V消息隊列(大量使用)

3,鍵值:消息隊列的內核持續性要求每個消息隊列都在系統範圍內對應唯一的鍵值,所以,要獲得一個消息隊列的描述符,必須提供該消息隊列的鍵值。

#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(char *pathname, char proj);
功能:返回文件名對應的鍵值。
pathname:文件名
proj:項目名(不爲0即可)

4,創建:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgget(key_t key, int msgflg)
key: 鍵值,由ftok獲得
msgflg:標誌位
返回值:與鍵值key相對應的消息隊列的描述符。
 

msglg取值:

IPC_CREAT:創建新隊列

IPC_EXCL 與IPC_CREAT一同使用,表示如果要創建的消息隊列已經存在,則返回錯誤。
IPC_NOWAIT 
 :讀寫消息隊列要求無法得到滿足時,不阻塞  

	//創建消息隊列
	//int msgget(key_t key, int msgflg);
	int msgid = msgget((key_t)123,0666 | IPC_CREAT);
	if(msgid == -1)
	{
		return -1;
	}
5,發送和接受消息

發送消息:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, struct msgbuf * msgp, int msgsz, int msgflg)
功能:向消息隊列中發送一條消息
msqid:消息隊列描述符
msgp:消息隊列指針,指向存放消息的結構
msgsz:消息數據長度
msgflg:發送標誌,有意義的msgflg標誌爲IPC_NOWAIT,指明在消息隊列沒有足夠空間容納要發送的消息時,msgsnd是否等待

接收消息:

#include <sys/ipc.h>
#include <sys/msg.h>
int msgrcv(int msqid, struct msgbuf* msgp, int msgsz, long msgtyp, int msgflg)
msqid:文字描述符
msgp:消息返回後存儲在msgp指向的地址
msgsz:指定msgbuf的mtext成員的長度,即消息內容的長度
msgtyp:請求讀取的消息類型
成功則返回讀取消息的字節數,否則返回-1。
功能:從msqid代表的消息隊列中讀取一個msgtyp類型的消息,並把消息存儲在msgp指向的msgbuf結構中。在成功的讀取了一條消息以後,隊列中的這條消息將被刪除。

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <stdio.h>

struct msgbuf 
{
	long mtype;     /* message type, must be > 0 */
	char mtext[1024];  /* message data */
};

int main()
{
	//創建消息隊列
	//int msgget(key_t key, int msgflg);
	int msgid = msgget((key_t)123,0666 | IPC_CREAT);
	if(msgid == -1)
	{
		perror("msgget ");
		return -1;
	}
	
	struct msgbuf msg;
	msg.mtype = 2;
	strcpy(msg.mtext,"CSDN");
	
	//發送消息
	//int msgsnd(int msqid, struct msgbuf * msgp, int msgsz, int msgflg)
	int ret = msgsnd(msgid,&msg,1024,IPC_NOWAIT);
	if(ret == -1)
	{
		perror("msgsnd ");
		return -1;
	}
	//接收消息
	//ssize_t msgrcv(int msqid, void *msgp, size_t msgsz,  long msgtyp, int msgflg);
	int ret2 = msgrcv(msgid,&msg,1024,2,IPC_NOWAIT);
	if(ret2 == -1)
	{
		perror("msgrcv ");
		return -1;
	}
	
	printf("%s\n",msg.mtext);
	
	return 0;
}
輸出結果:
[root@promote 4-消息隊列]# gcc 1-消息隊列.c 
[root@promote 4-消息隊列]# ./a.out 
CSDN
6,消息隊列控制:

int msgctl(int msgid, int command, struct msgid_ds *buf);  
 
command是將要採取的動作,它可以取3個值,
    IPC_STAT:把msgid_ds結構中的數據設置爲消息隊列的當前關聯值,即用消息隊列的當前關聯值覆蓋msgid_ds的值。
    IPC_SET:如果進程有足夠的權限,就把消息列隊的當前關聯值設置爲msgid_ds結構中給出的值
    IPC_RMID:刪除消息隊列
 
buf是指向msgid_ds結構的指針,它指向消息隊列模式和訪問權限的結構。msgid_ds結構至少包括以下成員:
struct msgid_ds  
{  
    uid_t shm_perm.uid;  
    uid_t shm_perm.gid;  
    mode_t shm_perm.mode;  
};  
成功時返回0,失敗時返回-1.

發佈了58 篇原創文章 · 獲贊 12 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章