什麽是消息隊列?
消息隊列提供了將數據塊從壹個進程發送到另壹個進程的方法。每個數據塊被認為包含壹種類型,接收過程可以獨立地接收包含不同類型的數據結構。我們可以通過發送消息來避免命名管道的同步和阻塞問題。但是像命名管道壹樣,消息隊列對每個數據塊都有最大長度限制。
Linux使用宏MSGMAX和MSGMNB來限制消息和隊列的最大長度。
第二,在Linux中使用消息隊列
Linux提供了壹系列消息隊列的函數接口,方便我們使用它來實現進程間的通信。它的用法類似於另外兩種System V PIC機制,即信號量和* * *共享內存。
1,msgget函數
該函數用於創建和訪問消息隊列。它的原型是:
int msgget(key_t,key,int msg flg);
像其他IPC機制壹樣,程序必須提供壹個鍵來命名特定的消息隊列。Msgflg是權限標誌,表示消息隊列的訪問權限,與文件的訪問權限相同。Msgflg可以和IPC_CREAT進行OR操作,意思是當key命名的消息隊列不存在時創建壹個消息隊列。如果存在由key命名的消息隊列,IPC_CREAT標誌將被忽略,只返回壹個標識符。
它返回名為key的消息隊列的標識符(非零整數),如果失敗,則返回-1。
2.msgsnd功能
該函數用於向消息隊列添加消息。它的原型是:
int msgsend(int msgid,const void *msg_ptr,size_t msg_sz,int msgflg);
Msgid是msgget函數返回的消息隊列標識符。
Msg_ptr是指向要發送的消息的指針,但是消息的數據結構有壹定的要求。指針msg_ptr指向的消息結構必須以壹個長整型成員變量開頭,接收函數會用這個成員來確定消息的類型。因此,消息結構應定義如下:
構造我的消息{
長整型message _ type
/*您希望傳輸的數據*/
};
Msg_sz是msg_ptr指向的消息長度。註意是消息的長度,而不是整個結構的長度,也就是說msg_sz是不包括長整型消息類型成員變量的長度。
Msgflg用於控制當當前消息隊列已滿或排隊的消息達到系統範圍的限制時會發生什麽。
如果調用成功,將消息數據的副本放入消息隊列並返回0,如果調用失敗,將返回-1。
3.msgrcv函數
這個函數用於從消息隊列中獲取消息,它的原型是
int msgrcv(int msgid,void *msg_ptr,size_t msg_st,long int msgtype,int msgflg);
msgid、msg _ ptr和msg _ ST的功能與msgsnd的功能相同。
Msgtype可以實現簡單的接收優先級。如果msgtype為0,則獲取隊列中的第壹條消息。如果其值大於零,將獲得具有相同消息類型的第壹條消息。如果小於零,則獲取類型等於或小於msgtype絕對值的第壹條消息。
Msgflg用於控制當隊列中沒有相應類型的消息要接收時會發生什麽。
當調用成功時,函數返回放入接收緩沖區的字節數,消息被復制到msg_ptr指向的用戶分配的緩沖區,然後消息隊列中對應的消息被刪除。失敗時返回-1。
4.msgctl函數
該函數用於控制消息隊列。它類似於帶* * *存儲器的shmctl函數。它的原型是:
int msgctl(int msgid,int command,struct msgid _ ds * buf);
命令是要采取的操作,它可以有三個值。
IPC_STAT:將msgid_ds結構中的數據設置為消息隊列的當前關聯值,即用消息隊列的當前關聯值覆蓋msgid_ds的值。
IPC_SET:如果進程有足夠的權限,將消息隊列的當前相關值設置為msgid_ds結構中給定的值。
IPC_RMID:刪除消息隊列
Buf是指向msgid_ds結構的指針,它指向消息隊列模式和訪問權限的結構。msgid_ds結構至少包括下列成員:
結構msgid_ds
{
uid _ t shm _ perm.uid
uid _ t shm _ perm.gid
mode _ t shm _ perm.mode
};
成功時返回0,失敗時返回-1。
第三,使用消息隊列進行進程間通信。
在介紹了消息隊列的定義和可用的接口之後,讓我們看看它是如何使進程能夠通信的。因為不相關的進程可以互相通信,所以我們在這裏會寫兩個程序,msgreceive和msgsned,來表示接收和發送信息。在正常情況下,我們允許兩個程序都創建消息,但只有在接收方收到最後壹條消息後,才會刪除它。
接收信息的程序的源文件是msgreceive.c,源代碼是:
# include & ltunistd.h & gt
# include & ltstdlib.h & gt
# include & ltstdio.h & gt
# include & ltstring.h & gt
# include & lt錯誤號& gt
# include & ltsys/msg . h & gt;
結構消息_st
{
長整型消息類型;
char text[BUFSIZ];
};
int main()
{
int running = 1;
int msgid =-1;
struct msg_st數據;
long int msg type = 0;//註1
//建立消息隊列
msgid = msgget((key_t)1234,0666 | IPC _ CREAT);
if(msgid == -1)
{
fprintf(stderr," msgget失敗,錯誤為:%d\n ",errno);
退出(EXIT _ FAILURE);
}
//從隊列中獲取消息,直到遇到結束消息。
(跑步時)
{
if(msgrcv(msgid,(void *)& amp;data,BUFSIZ,msgtype,0) == -1)
{
fprintf(stderr," msgrcv失敗,錯誤號:%d\n ",錯誤號);
退出(EXIT _ FAILURE);
}
printf("妳寫了:%s\n ",data . text);
//遇到結尾
if(strncmp(data.text," end ",3) == 0)
跑步= 0;
}
//刪除消息隊列
if(msgctl(msgid,IPC_RMID,0) == -1)
{
fprintf(stderr," msgctl(IPC_RMID)失敗\ n ");
退出(EXIT _ FAILURE);
}
退出(EXIT _ SUCCESS);
}
發送信息的程序的源文件msgsend.c的源代碼是:
# include & ltunistd.h & gt
# include & ltstdlib.h & gt
# include & ltstdio.h & gt
# include & ltstring.h & gt
# include & ltsys/msg . h & gt;
# include & lt錯誤號& gt
#define MAX_TEXT 512
結構消息_st
{
長整型消息類型;
char TEXT[MAX _ TEXT];
};
int main()
{
int running = 1;
struct msg_st數據;
char buffer[BUFSIZ];
int msgid =-1;
//建立消息隊列
msgid = msgget((key_t)1234,0666 | IPC _ CREAT);
if(msgid == -1)
{
fprintf(stderr," msgget失敗,錯誤為:%d\n ",errno);
退出(EXIT _ FAILURE);
}
//將消息寫入消息隊列,直到寫完為止。
(跑步時)
{
//輸入數據
printf("輸入壹些文本:");
fgets(buffer,BUFSIZ,stdin);
data . msg _ type = 1;//註2
strcpy(data.text,buffer);
//將數據發送到隊列
if(msgsnd(msgid,(void *)& amp;data,MAX_TEXT,0) == -1)
{
fprintf(stderr," msgsnd失敗\ n ");
退出(EXIT _ FAILURE);
}
//輸入end結束輸入。
if(strncmp(buffer," end ",3) == 0)
跑步= 0;
睡眠(1);
}
退出(EXIT _ SUCCESS);
}
轉載僅供參考,版權歸原作者所有。祝妳有愉快的壹天。滿意請采納。