WaitForMultipleObjects()等待多个对象

_Tiny 2012-10-22 12:39:09
HANDLE hEvents[5];
DWORD nEventIdx;
int nIndex = 0;
int nCount = sizeof(hEvents)/sizeof(hEvents[0]);
hEvents[0] = pthis->m_hEvProcessStop;
hEvents[1] = pthis->m_h1;
hEvents[2] = pthis->m_h2;
hEvents[3] = pthis->m_h3;
hEvents[4] = pthis->m_h4;

// Main thread loop
while(1)
{
// Wait for an event to be signalled
nEventIdx=WaitForMultipleObjects(nCount,hEvents,FALSE,200);

// If the stop event, stop looping and exit
if(nEventIdx==0)
break;

// Process signal events
switch(nEventIdx)
{
case 1:
pthis->function1();
break;
case 2:
pthis->function2();
break;
case 3:
pthis->function3();
break;
case 4:
pthis->function4();
break;
}


return (0);
}

function4本来是另外一个工程中的,是实现跟前3个不同功能的一个线程,分开的时候好好的,把function4加入进来之后function4就不会执行了,但是设置断点单步调试的时候偶尔会触发该事件!是不是因为多个内核对象被触发时,WaitForMultipleObjects选择其中序号最小的返回。而WaitForMultipleObjects它只会改变使它返回的那个内核对象的状态。如果序号最小的那个对象频繁被触发,那么序号比它大的内核对象将得不到被处理的机会。 是这样子吗?那么用双WaitForMultipleObjects的话需要怎么改?还请大神们指教啊,先在此拜谢了~
...全文
1245 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
Joseph-Growth 2012-10-26
  • 打赏
  • 举报
回复
while(1)
{
// Wait for an event to be signalled
nEventIdx=WaitForMultipleObjects(nCount,hEvents,FALSE,200);

// If the stop event, stop looping and exit
if(nEventIdx==0)
break;

// Process signal events
switch(nEventIdx)
{
case 1:
pthis->function1();
break;
case 2:
pthis->function2();
break;
case 3:
pthis->function3();
break;
case 4:
pthis->function4();
break;
}

我想这个写法也是有问题的。
WaitForMultipleObjects执行后,受信信号量会被置为非受信。
这里楼主执行functionX函数,阻塞了这个while循环其他信号量的检验过程。

个人愚见,这里执行functionX函数可不可以变成异步处理。即这里只标识某个变量(或是信号量),避免执行时间较长的函数体。并且该函数体中还对WaitForMultipleObjects的信号体有受信操作。
_Tiny 2012-10-26
  • 打赏
  • 举报
回复
还是你懂我,太菜了哦…………[Quote=引用 25 楼 的回复:]

隐约感觉这可能是个低级错误,合并的时候出得。
[/Quote]
leisure_cloud 2012-10-25
  • 打赏
  • 举报
回复
隐约感觉这可能是个低级错误,合并的时候出得。
easyrem 2012-10-25
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 的回复:]
为了解决这一问题,可以采用双WaitForMultipleObjects检测机制来实现。见下面的例子:

C/C++ code

DWORD WINAPI ThreadProc(LPVOID lpParameter)   {   DWORD dwRet = 0;   int nIndex = 0;   while(1)   {   dwRet = WaitForMultipleObjec……
[/Quote]

排版不对 你自己看百科把
easyrem 2012-10-25
  • 打赏
  • 举报
回复
为了解决这一问题,可以采用双WaitForMultipleObjects检测机制来实现。见下面的例子:

DWORD WINAPI ThreadProc(LPVOID lpParameter)   {   DWORD dwRet = 0;   int nIndex = 0;   while(1)   {   dwRet = WaitForMultipleObjects(nCount,pHandles,false,INFINITE);   switch(dwRet)   {   case WAIT_TIMEOUT:   break;   case WAIT_FAILED:   return 1;   default:   {   nIndex = dwRet - WAIT_OBJECT_0;   ProcessHanlde(nIndex++);   //同时检测其他的事件   while(nIndex < nCount) //nCount事件对象总数   {   dwRet = WaitForMultipleObjects(nCount - nIndex,&pHandles[nIndex],false,0);   switch(dwRet)   {   case WAIT_TIMEOUT:   nIndex = nCount; //退出检测,因为没有被触发的对象了.   break;   case WAIT_FAILED:   return 1;   default:   {   nIndex = nIndex + dwRet - WAIT_OBJECT_0;   ProcessHanlde(nIndex++);   }   break   }   }   }   break;   }   }   return 0;   }

看百科上的。
_Tiny 2012-10-24
  • 打赏
  • 举报
回复
单步调试的时候发现事件是有值的,为什么没等到呢?谁要是跟我说这个事件没触发,所以没等到,那为什么不触发呢?哎,看来又要含恨而终了!!!!!!!!!???????????????
_Tiny 2012-10-23
  • 打赏
  • 举报
回复
…………各种猜测都采取一定的方法试过了,为什么还是不行呢,跪求大神降临,神呐,赐我个大神吧!!!!!!
_Tiny 2012-10-22
  • 打赏
  • 举报
回复
这个我试过的不行的![Quote=引用 18 楼 的回复:]

假如有多个信号返回,返回的是最小的,你把hEvents[4] = pthis->m_h4;放前面试试。
[/Quote]
flytask 2012-10-22
  • 打赏
  • 举报
回复
假如有多个信号返回,返回的是最小的,你把hEvents[4] = pthis->m_h4;放前面试试。
_Tiny 2012-10-22
  • 打赏
  • 举报
回复
好吧,我试试。非常感谢![Quote=引用 14 楼 的回复:]

如果要解决,就要根据事件的触发速度分组,速度相近的分一组,然后每一组分别在不同的线程里面调用WaitForMultipleObjects。
[/Quote]
Joseph-Growth 2012-10-22
  • 打赏
  • 举报
回复
Mark!没看懂
_Tiny 2012-10-22
  • 打赏
  • 举报
回复
嗯,非常感谢您能帮我看看,我的工程不可能所有事件同时都触发,等待所有事件是不现实的,所以bWaitAll我设置的是FALSE。那有大量事件需要处理的时候我该怎么做呢,是否需要使用大家所说的双WaitForMultipleObjects来处理?如果要用这种方式处理的话我该怎么改呢?
[Quote=引用 13 楼 的回复:]

这个问题应该存在,但我在现实中很少去处理它,WaitForMultipleObjects用来处理大量的事件的情况应该要避免。

如果不等待所有事件,WaitForMultipleObjects每次都返回最前面的,已经碱触发状态了的对象,很明显后面的可能出现饥饿现象。

WaitForMultipleObjects需要你提供一个数组,所以系统将不会为其分配句柄(像iocp一样),如果没有分……
[/Quote]
youngwolf 2012-10-22
  • 打赏
  • 举报
回复
如果要解决,就要根据事件的触发速度分组,速度相近的分一组,然后每一组分别在不同的线程里面调用WaitForMultipleObjects。
youngwolf 2012-10-22
  • 打赏
  • 举报
回复
这个问题应该存在,但我在现实中很少去处理它,WaitForMultipleObjects用来处理大量的事件的情况应该要避免。

如果不等待所有事件,WaitForMultipleObjects每次都返回最前面的,已经碱触发状态了的对象,很明显后面的可能出现饥饿现象。

WaitForMultipleObjects需要你提供一个数组,所以系统将不会为其分配句柄(像iocp一样),如果没有分句柄(即一个系统内部使用的数据结构),它就没办法知道上一次返回的是哪一个事件(以便下次从下一个事件开始判断,以解决饥饿问题)。
_Tiny 2012-10-22
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 的回复:]

我都怀疑你直接运行

pthis->function4();

都有问题。
[/Quote]

CxxDlg *pthis=(CxxCDlg *) pParam;
HANDLE hEvents[2];
int nEventIdx = 0;

// Configure events to be listened on
hEvents[0]=pthis->m_hEvNuiProcessStop;

hEvents[1]=pthis->m_h4;

// Main thread loop
while(1)
{
// Wait for an event to be signalled
nEventIdx=WaitForMultipleObjects(sizeof(hEvents)/sizeof(hEvents[0]),hEvents,FALSE,200);

// If the stop event, stop looping and exit
if(nEventIdx==0)
break;

if (nEventIdx==1)
{
pthis->function4();
}
}
在CxxDlg的工程中运行没有问题,把这个事件添加到CXXXDlg的工程中就不行了,CXXXDlg的工程中之前是有m_h1,m_h2,m_h3等3个事件的,不管添加不添加m_h4事件这3个事件处理都没有问题!就是把m_h4事件添加到CXXXDlg工程中该事件的处理函数function4就不能执行了,始终找不到原因!希望能帮我分析下到底是什么原因~
傻X 2012-10-22
  • 打赏
  • 举报
回复
我都怀疑你直接运行

pthis->function4();

都有问题。
_Tiny 2012-10-22
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]

调试过程中发现WaitForMultipleObjects函数返回值为258,这个说明什么问题?
[/Quote]
经调试发现258应该为等待失败返回了等待时间的值!
CXXXDlg *pthis=(CXXXDlg *) pParam;
HANDLE hEvents[2];
int nEventIdx = 0;

// Configure events to be listened on
hEvents[0]=pthis->m_hEvNuiProcessStop;

hEvents[1]=pthis->m_h4;

// Main thread loop
while(1)
{
// Wait for an event to be signalled
nEventIdx=WaitForMultipleObjects(sizeof(hEvents)/sizeof(hEvents[0]),hEvents,FALSE,200);

// If the stop event, stop looping and exit
if(nEventIdx==0)
break;

if (nEventIdx==1)
{
pthis->function4();
}
}
我将上面的改为这样子,pthis->function4()也没有执行,这是为什么?
function1(),function2(),function3()在一个工程当中的时候是正常的,function4在另外一个工程中执行也是正常的,现在我就是讲两个工程合并了下而已。也就是说我刚才是注释掉123的事件句柄和事件处理函数,结果4也是不能执行,4注释掉或者不注释掉,都不会影响123的正常执行!这说明什么问题?还望路过的大神指点一二,这个问题困扰很久了,谢谢……
_Tiny 2012-10-22
  • 打赏
  • 举报
回复
调试过程中发现WaitForMultipleObjects函数返回值为258,这个说明什么问题?
_Tiny 2012-10-22
  • 打赏
  • 举报
回复
我现在的问题是怎么根据那个双WaitForMultipleObjects的例子修改我的代码,麻烦大家帮我改改,先行谢过了~
xyddz 2012-10-22
  • 打赏
  • 举报
回复
应该不会有这种情况吧。
下标应该是 nEventIdx - WAIT_OBJECT_0
加载更多回复(6)
实验一 生产者-消费者模型模拟进程调度 一、实验任务 1、在WINDOWS 2000环境下,创建一个控制台进程,此进程包括4个线程:2个生产者线程和2个消费者线程。 2、用信号量机制解决进程(线程)的同步与互斥问题。 二、实验目的 1.掌握基本的同步互斥算法,理解生产者和消费者模型。 2.了解Windows 2000/XP中多线程的并发执行机制,线程间的同步和互斥。 3.学习使用Windows 2000/XP中基本的同步对象,掌握相应的API。 三、实验要求 1.生产者消费者对缓冲区进行互斥操作。 2.缓冲区大小为10,缓冲区满则不允许生产者生产数据,缓冲区空则不允许消费者消费数据。 3.生产者消费者各循环操作50次。 四、设计思路和采取的方案 1.利用windows提供的API函数CreateSemaphore()创建信号量对象; CreateThread()创建线程; WaitForSingleObject()执行P操作; ReleaseSemaphore()执行V操作; WaitForMultipleObjects()主进程等待线程的结束等函数进行设计。 2.在Windows中,常见的同步对象有:信号量(Semaphore)、互斥量(Mutex) 。 使用这些对象都分为三个步骤,一是创建或者初始化; 接着请求该同步对象,随即进入临界区,这一步对应于互斥量的上锁;最后释放该同步对象,这对应于互斥量的解锁。这些同步对象在主进程中创建,在其子线程中都可。

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧