Linux编程 消息队列

jingweiyoung 发布于 2012/06/01 17:57
阅读 803
收藏 0

主要代码如下

程序运行时,手动ipcrm -Q 删掉其对应的消息队列,结果程序返回的errno却是EINVAL,

为什么不是EIDRM呢?这两者有什么区别?请教...

while( msgsnd(msgI,buf,iLen,0) )
{
	if( errno == EIDRM )
	{
		msgId = ReopenMsg(msgKey);
	}
	
	if( errno == EINTR )
	{
		LogPrn(3,1,"msgsnd,   EINTR : Interrupted system call\n sleep 2 seconds...");
		sleep(2);
	}
	
	if( errno == EINVAL )
	{
		....;
	}
	
}

以下是问题补充:

@jingweiyoung:而且我曾尝试在返回EINVAL后 sleep几秒,continue。结果返回的errno还是同样的 (2012/06/01 18:15)
@jingweiyoung:man手册里的官方说明 EIDRM Identifier removed (POSIX.1) EINVAL Invalid argument (POSIX.1) (2012/06/01 18:17)
加载中
0
一一无念
一一无念
EINVAL 是返回失效,表示没在当前消息队列
0
jingweiyoung
jingweiyoung

引用来自“一一无念”的答案

EINVAL 是返回失效,表示没在当前消息队列
为什么不是 EIDRM:消息队列已删除
0
一一无念
一一无念
-Q msgkey

              Remove the message queue identifier, created with key msgkey, from the system and destroy the message queue and data structure associated with it.

   

0
0
jingweiyoung
jingweiyoung
第一行代码是 while( msgsnd(msgId,buf,iLen,0) )
0
一一无念
一一无念
仔细看了下源码,没找到根本原因
0
中山野鬼
中山野鬼

楼主,我没试过你这个方式哈。。。手上系统暂时没linux我没办法测试。不过有点肯定。你是在删除消息队列后,才调用msgsnd。而且外部删除导致msgId此时非法。因此直接返回EINVAL。

而如果msgId不非法,但在调用中发现资源不存在。就是消息队列不存在,则返回EIDRM。

你可以常识,不使用外部删除消息队列的方式,自己的程序实现,在msgsnd调用的间隙,仅移除消息队列,但保证msgId的合法性。则EIDRM还是会出现的。

我给你举个例子:

假设,你需要打开一个文件,读取A和B,进行计算。A,B可以看做是你要计算的资源。没有他们你无法实现计算。但首先要保证文件指针的合法性。如果文件指针都已经非法,就不存在判断A,B的资源是否存在的问题。

不知道你是否理解。

你在外部删除消息队列,这个资源已经丢失,没错,但同时msgId也变成了非法指针(用指针比较好描述吧,我不太喜欢用句柄,索引,来描述)。

返回顶部
顶部