返回信息流情况如下:
设置了一个全局变量HANDLE g_hevInt[3];
在程序里创建了三个事件:
g_hevInt[0] = CreateEvent(NULL,FALSE,FALSE,NULL);
g_hevInt[1] = CreateEvent(NULL,FALSE,FALSE,NULL);
g_hevInt[2] = CreateEvent(NULL,FALSE,FALSE,NULL);
这三个事件和中断相关,有中断发生则事件有效。
然后在IST这个线程里等待事件的发生。
第一次中断产生调用WaitForMultipleObjects函数得到的事件和相应的响应都是正确的。
但是接下来WaitForMultipleObjects一直返回WAIT_FAILED,不知是什么原因?
GetLastError()返回值是6,即INVALID HANDLE
但是我输出三个句柄的值以及g_hevInt的值,发现第一次调用时和返回WAIT_FAILED时的值都是一致的,那为什么会产生这个错误呢?
还请大家帮忙分析一下。^_^,谢谢。
线程回调函数代码如下:
DWORD IST(LPVOID pArg)
{
DWORD ret;
while (1)
{
ret = WaitForMultipleObjects(3,g_hevInt,FALSE,INFINITE);
if(ret == WAIT_FAILED)
{
RETAILMSG(1,(TEXT("WAIT_FAILED here.\r\n")));
RETAILMSG(1, (L"LastError = %d \r\n", GetLastError()));
}
else if (ret != WAIT_TIMEOUT)
{
RETAILMSG(1, (L"Event [%d] is triggered.\r\n", ret));
ResetEvent(g_hevInt[ret]);
InterruptDone(g_EINTSysIntr[ret]);
}
else
{
RETAILMSG(1,(TEXT("EINT_IntrThread Exit.\r\n")));
return 0;
}
}
return 1;
}
这是一条镜像帖。来源:北邮人论坛 / soft-design / #27947同步于 2008/7/9
该镜像源已超过 30 天没有更新,可能在源站已被删除。
SoftDesign机器人发帖
WaitForMultipleObjects返回WAIT_FAILED的问题
snowbluff
2008/7/9镜像同步12 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
嗯,是这样的,因为你已经wait成功一次了,这就说明这三个events对象中至少有一个的标示位被置为signaled,应该需要手动把对象置回到unsignaled状态,才能继续进行wait,这个waitforobject系列函数的实际过程就是去判断object的signal标示位
CreateEvent的第三个参数设置为FALSE的话Waitforobject得到事件后会自动清信号的状态的。而且现在我已经调用resetevent手动又清了一次没有效果。
如果只是一个event的话用WaitForSingleObject的话没有问题。
现在是既然事件句柄的值在第一次正常的时候和以后异常的时候都是一致的,那为什么 WaitForMultipleObjects会认为是错误的而返回,并且这个错误时INVAILD HANDLE?
有没有办法判断一个句柄是否有效?
【 在 rebirthatsix 的大作中提到: 】
: 嗯,是这样的,因为你已经wait成功一次了,这就说明这三个events对象中至少有一个的标示位被置为signaled,应该需要手动把对象置回到unsignaled状态,才能继续进行wait,这个waitforobject系列函数的实际过程就是去判断object的signal标示位
额,== INVALID_HANDLE_VALUE,这个判断你这个还是不行,得检测句柄对应的对象是不是被销毁了,但是连Closehandle都没有调用,计数8可能是0阿,对象咋可能随便就被销毁了
你说的循环wait是啥意思?类似这样的?
DWORD IST(LPVOID pArg)
{
DWORD ret;
while (1)
{
if(WAIT_OBJECT_0==WaitForSingleObject(g_hevInt[0],100))
{
RETAILMSG(1, (L"Event 0 is triggered.\r\n"));
}
if(WAIT_OBJECT_0==WaitForSingleObject(g_hevInt[1],100))
{
RETAILMSG(1, (L"Event 1 is triggered.\r\n"));
}
if(WAIT_OBJECT_0==WaitForSingleObject(g_hevInt[2],100))
{
RETAILMSG(1, (L"Event 2 is triggered.\r\n"));
}
}
return 1;
}
我在VC里用WaitForMultiObject写了类似的程序也没有任何问题。。。
现在算是找到了点原因。
事件和中断是通过InterruptInitialize关联起来的,在InterruptInitialize的文档里说:
The hEvent parameter can only be used in a WaitForSingleObject call to wait for the event to be triggered by the kernel.
A WaitForMultipleObjects call with hEvent will fail.
现在有两个疑问:
1.我想在一个线程里同时等待几个中断事件的发生,上面我写的这种方式如果可以用的话貌似实时性不太好。三个事件的优先级轮转了。有没有别的比较好一点的方式可以采用?
2.help上关于InterruptInitialize的说明里说。
A WaitForMultipleObjects call with hEvent will fail。按字面的意思好像是第一次调用也不会成功?但是现在第一次调用WaitForMultipleObjects是正确的,而之后出错时我打印事件句柄的值,包括g_hevInt这个地址的值都没有发生任何变化。也就是好像句柄值并未失效?这样的话为什么会出错呢?
我试过
if(!g_hevInt[0])
{
RETAILMSG;
}
和
if(g_hevInt[0]==INVALID_HANDLE_VALUE)
{
RETAILMSG;
}
这两种方式判断句柄是否有效,但是都没有问题啊。。。
太奇怪了。
WaitForMultipleObjects结束后只是把那个事件置位无信号状态,但是为什么会对于InterruptInitialize 的时间不能用呢,太奇怪了。而且根据测试结果好像句柄的值也没有变化啊。。。
ps1:用一个event,WaitForSingleObject是OK的,没问题。
ps2:这个是Windows CE下的driver.
ps3:线程时间片的大小是固定的?还是根据线程的多少由操作系统调整?怎么样可以得到这个时间片的大小?
【 在 rebirthatsix 的大作中提到: 】
: 写了一个和你类似的,循环wait,没出你这个错,感觉可能你的中断处理例程可能有问题
wince driver,不做评论。
话说我前几天刚完整的逆向了NtWaitForSingleObject/KeWaitForSingleObject,
明白了不少东西。
【 在 snowbluff (18CrMnTi|≮雪域≯之雪崖) 的大作中提到: 】
: 你说的循环wait是啥意思?类似这样的?
: DWORD IST(LPVOID pArg)
: {
: ...................
在生命周期结束之前被赋予的句柄值就不会改变了,即使他指向的对象被销毁了?
怎么判断一个句柄的对象是否被销毁了?找了好久没找到着呢么判断的。。。
【 在 rebirthatsix 的大作中提到: 】
: 额,== INVALID_HANDLE_VALUE,这个判断你这个还是不行,得检测句柄对应的对象是不是被销毁了,但是连Closehandle都没有调用,计数8可能是0阿,对象咋可能随便就被销毁了
赞。^_^
可以讲一下这两函数实际实现的功能和过程与原先以为的功能有什么差别么?
呵呵。我关系的东西是不是太表象了。。。
【 在 flyingkisser 的大作中提到: 】
: wince driver,不做评论。
: 话说我前几天刚完整的逆向了NtWaitForSingleObject/KeWaitForSingleObject,
: 明白了不少东西。
一般来说,销毁一个对象之后,句柄立马赋值空,然后就可以用是否为空来判断
【 在 snowbluff 的大作中提到: 】
: 在生命周期结束之前被赋予的句柄值就不会改变了,即使他指向的对象被销毁了?
: 怎么判断一个句柄的对象是否被销毁了?找了好久没找到着呢么判断的。。。