您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“Linux編程消息隊列相關(guān)的函數(shù)有哪些”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
消息隊列本質(zhì)上是位于內(nèi)核空間的鏈表,鏈表的每個節(jié)點都是一條消息。每一條消息都有自己的消息類型,消息類型用整數(shù)來表示,而且必須大于 0。每種類型的消息都被對應(yīng)的鏈表所維護(hù):
其中數(shù)字 1 表示類型為 1 的消息,數(shù)字2、3、4 類似。彩色塊表示消息數(shù)據(jù),它們被掛在對應(yīng)類型的鏈表上。
值得注意的是,剛剛說過沒有消息類型為 0 的消息,實際上,消息類型為 0 的鏈表記錄了所有消息加入隊列的順序,其中紅色箭頭表示消息加入的順序。
// 創(chuàng)建和獲取 ipc 內(nèi)核對象 int msgget(key_t key, int flags); // 將消息發(fā)送到消息隊列 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); // 查看、設(shè)置、刪除 ipc 內(nèi)核對象(用法和 shmctl 一樣) int msgctl(int msqid, int cmd, struct msqid_ds *buf);
無論你是發(fā)送還是接收消息,消息的格式都必須按照規(guī)范來。簡單的說,它一般長成下面這個樣子:
struct Msg{ long type; // 消息類型。這個是必須的,而且值必須 > 0,這個值被系統(tǒng)使用 // 消息正文,多少字節(jié)隨你而定 // ... };
所以,只要你保證首4字節(jié)(32 位 linux 下的 long)是一個整數(shù)就行了。 舉個例子:
struct Msg { long type; char name[20]; int age; } msg; struct Msg { long type; int start; int end; } msg;
從上面可以看出,正文部分是什么數(shù)據(jù)類型都沒關(guān)系,因為消息隊列傳遞的是 2 進(jìn)制數(shù)據(jù),不一定非得是文本。
msgsnd 函數(shù)用于將數(shù)據(jù)發(fā)送到消息隊列。如果該函數(shù)被信號打斷,會設(shè)置 errno 為 EINTR。
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
參數(shù) msqid:ipc 內(nèi)核對象 id 參數(shù) msgp:消息數(shù)據(jù)地址 參數(shù) msgsz:消息正文部分的大?。ú话㈩愋停?參數(shù) msgflg:可選項 該值為 0:如果消息隊列空間不夠,msgsnd 會阻塞。 IPC_NOWAIT:直接返回,如果空間不夠,會設(shè)置 errno 為 EAGIN.
返回值:0 表示成功,-1 失敗并設(shè)置 errno。
msgrcv 函數(shù)從消息隊列取出消息后,并將其從消息隊列里刪除。
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
參數(shù) msqid:ipc 內(nèi)核對象 id 參數(shù) msgp:用來接收消息數(shù)據(jù)地址 參數(shù) msgsz:消息正文部分的大?。ú话㈩愋停?參數(shù) msgtyp:指定獲取哪種類型的消息
msgtyp = 0:獲取消息隊列中的第一條消息 msgtyp > 0:獲取類型為 msgtyp 的第一條消息,除非指定了 msgflg 為MSG_EXCEPT,這表示獲取除了 msgtyp 類型以外的第一條消息。 msgtyp 0 的情況。表示獲取類型不為 msgtyp 的消息 MSG_NOERROR:如果消息數(shù)據(jù)正文內(nèi)容大于 msgsz,就將消息數(shù)據(jù)截斷為 msgsz
程序 msg_send 和 msg_recv 分別用于向消息隊列發(fā)送數(shù)據(jù)和接收數(shù)據(jù)。
msg_send 程序定義了一個結(jié)構(gòu)體 Msg,消息正文部分是結(jié)構(gòu)體 Person。該程序向消息隊列發(fā)送了 10 條消息。 msg_send.c
#include #include #include #include #include typedef struct { char name[20]; int age; }Person; typedef struct { long type; Person person; }Msg; int main(int argc, char *argv) { int id = msgget(0x8888, IPC_CREAT | 0664); Msg msg[10] = { {1, {"Luffy", 17}}, {1, {"Zoro", 19}}, {2, {"Nami", 18}}, {2, {"Usopo", 17}}, {1, {"Sanji", 19}}, {3, {"Chopper", 15}}, {4, {"Robin", 28}}, {4, {"Franky", 34}}, {5, {"Brook", 88}}, {6, {"Sunny", 2}} }; int i; for (i = 0; i 程序 msg_send 第一次運行完后,內(nèi)核中的消息隊列大概像下面這樣:6.2 msg_recvmsg_recv 程序接收一個參數(shù),表示接收哪種類型的消息。比如./msg_recv 4 表示接收類型為 4 的消息,并打印在屏幕。 #include #include #include #include #include #include #include typedef struct { char name[20]; int age; }Person; typedef struct { long type; Person person; }Msg; void printMsg(Msg *msg) { printf("{ type = %ld, name = %s, age = %d }\n", msg->type, msg->person.name, msg->person.age); } int main(int argc, char *argv[]) { if (argc \n", argv[0]); return -1; } // 要獲取的消息類型 long type = atol(argv[1]); // 獲取 ipc 內(nèi)核對象 id int id = msgget(0x8888, 0); Msg msg; int res; while(1) { // 以非阻塞的方式接收類型為 type 的消息 res = msgrcv(id, &msg, sizeof(Person), type, IPC_NOWAIT); if (res 6.3 編譯 [root@localhost ~]# gcc msg_send.c -o msg_send [root@localhost ~]# gcc msg_recv.c -o msg_recv6.4 運行先運行 msg_send,再運行 msg_recv。 接收所有消息image.png接收類型為 4 的消息image.pngmsgctl函數(shù)獲取和設(shè)置消息隊列的屬性 int msgctl(int msqid, int cmd, struct msqid_ds *buf);msqid:消息隊列標(biāo)識符 cmd:控制指令 IPC_STAT:獲得msgid的消息隊列頭數(shù)據(jù)到buf中 IPC_SET:設(shè)置消息隊列的屬性,要設(shè)置的屬性需先存儲在buf中,可設(shè)置的屬性包括:msg_perm.uid、msg_perm.gid、msg_perm.mode以及msg_qbytes buf:消息隊列管理結(jié)構(gòu)體。返回值: 成功:0 出錯:-1,錯誤原因存于error中 EACCESS:參數(shù)cmd為IPC_STAT,確無權(quán)限讀取該消息隊列 EFAULT:參數(shù)buf指向無效的內(nèi)存地址 EIDRM:標(biāo)識符為msqid的消息隊列已被刪除 EINVAL:無效的參數(shù)cmd或msqid EPERM:參數(shù)cmd為IPC_SET或IPC_RMID,卻無足夠的權(quán)限執(zhí)行實例 #include #include #include #include #include #include struct msgbuf{ long mtype ; char mtext[] ; } ; int main(int argc, char **argv){ int msqid ; struct msqid_ds info ; struct msgbuf buf ; struct msgbuf buf1 ; int flag ; int sendlength, recvlength ; msqid = msgget( IPC_PRIVATE, 0666 ) ; if ( msqid
“Linux編程消息隊列相關(guān)的函數(shù)有哪些”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。