WaitForMultipleObjects返回WAIT_FAILED的问题
情况如下:
设置了一个全局变量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;
}
WaitForMultipleObjects函数不能用于使用过“InterruptInitialize”函数的事件。
InterruptInitialize
只能用在WaitForSingleObject
而且
先InterruptInitialize
才能
WaitForSingleObject
先谢谢楼上两位。
有两个疑问:
1.我想在一个线程里同时等待几个中断事件的发生,这种方法不能用的话采取什么样的方式比较好?
2.help上关于InterruptInitialize的说明里说。
A WaitForMultipleObjects call with hEvent will fail。
第一次调用WaitForMultipleObjects是正确的,而之后出错时我打印事件句柄的值并没有任何变化,
也就是好像句柄值并未失效,这样的话为什么会出错呢?
ResetEvent(g_hevInt[ret]); //咦,这样envet就不可用了,干吗这样玩?
引用: 引用 4 楼 shuiyan 的回复:
ResetEvent(g_hevInt[ret]); //咦,这样envet就不可用了,干吗这样玩?
这个是我测试了以为这个事件需要手动清除信号状态,后来没用,:-)
你用一个event,WaitForSingleObject能成功吗?
WaitForMultipleObjects时,加判断,看看第一次到底是哪个event触发的。
改好后,看看驱动打印的消息。
to shuiyan:
用一个event,WaitForSingleObject是OK的,没问题。
WaitForMultipleObjects时,第一次event也确实是发生了的那个中断没问题。
而且出错时事件句柄的值,包括g_hevInt这个地址的值都没有发生任何变化。
我试过
if(!g_hevInt[0])
{
RETAILMSG;
}
和
if(g_hevInt[0]==INVALID_HANDLE_VALUE)
{
RETAILMSG;
}
这两种方式判断句柄是否有效,但是都没有问题啊。。。
太奇怪了。
WaitForMultipleObjects结束后只是把那个事件置位无信号状态,但是为什么会对于InterruptInitialize 的时间不能用呢,太奇怪了。而且根据测试结果好像句柄的值也没有变化啊。。。
msdn里没有的,不一定不能用。
msdn明确说不能用的,估计就是不能用。这个就是理由了。
好吧 。呵呵。
我想在一个线程里等待多个中断事件的话应该怎么做?我只想到下面一种方式,但是这种方式中断优先级轮转,实时性太差了,有没有别的方式可以实现这种要求的?
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;
}
只要不是用InterruptInitialize 初始化的都可以用
WaitForMultipleObjects
to lenux:
在这种情况下事件是使用InterruptInitialize和中断相关联的,如果不用这种方式的话,
在CE下还有什么方式可以判断中断是否发生然后进行处理呢?
ps:是否可以再BSPIntrActiveIrq函数中直接处理一下?不过这样做的话就违背了中断分为ISR和IST的方法了。。。貌似不太妥哇。。。
啊?还没取消用InterruptInitialize 对这几个event设置啊?
只要SetEvent之后,这些event就可以在WaitMultipleObjects里面使用了。
在别的地方(比如希望与该Event挂钩的中断线程)对其SetEvent()就行。
to shuiyan:
在别的地方(比如希望与该Event挂钩的中断线程)对其SetEvent()就行?
现在的情况是使用这个event是否有信号来判断中断是否发生。InterruptInitialize这个函数调用时会自动调用OALIntrEnableIrqs的,所以这种方式很难更改吧?
你的意思是每个中断起一个线程然后在该中断线程里SetEvent()?用两套event?
可能我有点没明白你的意思。可以描述下你的实现方式么?
或者是有不用InterruptInitialize而实现整个中断流程的方法?
有别的判断中断是否发生然后进行处理的方法?
ps:我是想在一个中断线程里对多个事件进行响应,就不用起一堆线程了。
to shuiyan:
在别的地方(比如希望与该Event挂钩的中断线程)对其SetEvent()就行?
现在的情况是使用这个event是否有信号来判断中断是否发生。InterruptInitialize这个函数调用时会自动调用OALIntrEnableIrqs的,所以这种方式很难更改吧?
你的意思是每个中断起一个线程然后在该中断线程里SetEvent()?用两套event?
可能我有点没明白你的意思。可以描述下你的实现方式么?
或者是有不用InterruptInitialize而实现整个中断流程的方法?
有别的判断中断是否发生然后进行处理的方法?
ps:我是想在一个中断线程里对多个事件进行响应,就不用起一堆线程了。
奇怪..用Waitforsingleobject()不行吗,为什么一定要用WaitMultipleObjects,
我试过WaitForSingleObject等待多个的,可以...处理完一个就close.
to xyj0663:
你处理的流程是啥样的?这样?
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;
}
好像真只有2套event了,一套SigleObject,在对应的ISR里面Set MultipleObjects里面的event。
ResetEvent(g_hevInt[ret - WAIT_OBJECT_0]);