msgsnd函式 msgrcv函式的一些小問題(IPC_NOWAIT慎用!)
這兩個函式別看它簡單,真的是一不小心就會出錯的啊
報錯1:msgsnd: Invalid argument
msgrcv: Argument list too long
這真的是一個最常見的錯誤了。。。歸根究底是緩衝區長度的問題
1⃣️這個問題我出錯後修復之後竟然無法重現錯誤了。。。等我下次遇到了再補這個錯誤吧,反正肯定就是緩衝區長度問題。
我寫的程式碼如下,輸出結果竟然為
*** cbytes: 8, qnum: 1,qbytes: 2048 ***
真的很不明白為什麼。。。
#include<stdio.h> #include<sys/msg.h> #include<errno.h> #include<stdlib.h> typedef struct msgbuf { long type; char data[1]; }message; int main(int argc, char const *argv[]) { int msqid; message ptr; struct msqid_ds buf; msqid = msgget(IPC_PRIVATE,IPC_CREAT|0644); if(msqid < 0) { perror("mssget"); } ptr.type = 1; //strcpy(ptr.data,"heihei"); ptr.data[0] = 1; int length = sizeof(message) - sizeof(long); if(msgsnd(msqid,&ptr,length,IPC_NOWAIT) < 0) { perror("msgsnd"); } msgctl(msqid,IPC_STAT,&buf); printf("cbytes: %lu, qnum: %lu,qbytes: %lu\n", buf.msg_cbytes, buf.msg_qnum,buf.msg_qbytes); return 0; }
2⃣️注意msgrcv裡面的length不能比你用msgsnd傳進來的長度要短,否則就會報第二個錯誤
比如:如果你msgsnd中length用sizeof(msgbuf)-sizeof(long)傳的,你的資料只有一個位元組,你在msgrcv中用sizeof(msgbuf.data)的話就會因為你的緩衝區不夠而報錯
報錯2;msgrcv: No message of desired type
在msgsnd函式終於安然無恙後,msgrcv函式又出亂子了,原因就是,我這句程式碼寫得不對
recvlength = msgrcv(msqid,&ptr,length,1,IPC_NOWAIT);
這段程式碼,在oflag位置我設定了IPC_NOWAIT,本想讓其不要一直阻塞的,結果錯就錯在這裡了。
首先明確,現在大家的機器都是多執行緒機器了。由於我設定了IPC_NOWAIT,會在佇列中沒有所需型別的訊息時,呼叫執行緒立即返回-1,沒有給msgrcv函式充足的時間把訊息放在佇列上,所以會一直返回-1。因此,我們還是把其設定為0吧,一直阻塞到佇列上有訊息為止。
對於在msgsnd函式中的IPC_NOWAIT,不管值不指定它,系統沒有足夠的空間的時候都不會阻塞。。。
另外要注意及時刪掉系統中的message queue哦!!!
一定要及時刪除!!! ipcrm -q + msqid / ipcrm -s + semaphore
不然會報錯
msgget: No space left on device