这两个函数别看它简单,真的是一不小心就会出错的啊
报错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