linux程序通訊:使用posix訊息佇列mq進行執行緒或程序間的通訊
阿新 • • 發佈:2019-02-06
POSIX訊息佇列允許程序以訊息的形式交換資料。此API與System V訊息佇列(msgget(2),msgsnd(2),msgrcv(2)等)有明顯不同,但做的事情差不多。
在linux多執行緒程式設計中,如果兩個執行緒沒用共同的資料區,則需要使用訊息佇列從一個執行緒往另一個執行緒傳送訊息(同樣可以應用在程序間通訊)
訊息佇列通過mq_open()建立和開啟,此函式返回一個訊息佇列描述符mqd_t,它用於之後的呼叫中引用開啟的訊息佇列。每個訊息佇列由一個名字標識,兩個程序可以操作同一個佇列。
訊息通過呼叫mq_send()和mq_receive()傳遞。當一個程序結束使用該佇列,則它呼叫mq_close(),當一個佇列不再需要了,則可以呼叫mq_unlink()刪除。佇列屬性可以呼叫mq_getattr()/mq_setattr()獲取/修改。一個程序可以在一個空佇列上呼叫mq_notify請求訊息到達的非同步通知。
訊息佇列描述符引用到一個開啟的訊息佇列(類比open(2))。fock(2)之後,子程序繼承父程序佇列描述符的拷貝,兩個描述符都引用到父程序的那個描述符。兩個程序持有的描述符共享與訊息佇列描述符相關聯的標記(mq_flags)。
下面以一個例項說明:
建立並接收資料執行緒:
傳送資料執行緒:#include<mqueue.h> #define WAIT_FOREVER -1 typedef struct{ UINT32 start; char name[32] = {0}; }MQ_SEND_MSG; //接收的訊息結構體 char nameMsg[32] = {0}; UINT32 memAvail; char chName; MQ_SEND_MSG recvMsg; extern mqd_t memAvailMsgQ; struct mq_addr mqa; mqa.mq_maxmsg = 20; mqa.mq_msgsize = sizeof(MQ_SEND_MSG); strcpy(nameMsg, "/memAvailMsgQ"); mqUnlink(nameMsg); memAvailMsgQ = mq_open(nameMsg, O_CREAT|O_RDWR|O_EXCL, DEFAULT_MSG_MODE, &mqa); //建立一個mq訊息 if(memAvailMsgQ == -1) { return error; } FOREVER //迴圈等待另一個執行緒傳送訊息 { retval = mq_receive(memAvailMsgQ, (char *)&recvSendMsg, sizeof(MQ_SEND_MSG), WAIT_FOREVER, NULL); if(retval == sizeof(MQ_SEND_MSG)) //mqReceive返回接收到的資料的長度,以此判斷有沒有成功接收訊息 { memAvail = recvSendMsg.start; chName = recvSendMsg.name; } }
#include<mqueue.h> typedef struct{ UINT32 start; char name[32] = {0}; }MQ_SEND_MSG; //mq訊息結構體 mqd_t memAvailMsgQ; //mq訊息控制代碼 MQ_SEND_MSG mqSendMsg; mqSendMsg.start = memAvail; //傳送的訊息結構體成員 strcpy(mqSendMsg.chName, "come on baby!"); //傳送的訊息結構體成員 mq_send(memAvailMsgQ, (char *)&mqSendMsg, sizeof(MQ_SEND_MSG), 200, 0); //傳送資料