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,不管值不指定它,系统没有足够的空间的时候都不会阻塞。。。

扫描二维码关注公众号,回复: 3926594 查看本文章

另外要注意及时删掉系统中的message queue哦!!!
一定要及时删除!!! ipcrm -q + msqid / ipcrm -s + semaphore
不然会报错msgget: No space left on device

猜你喜欢

转载自blog.csdn.net/qq_37414405/article/details/83586618