1. 程式人生 > >msgsnd函式 msgrcv函式的一些小問題(IPC_NOWAIT慎用!)

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