注册 登录
编程论坛 VC++/MFC

多线程 调用自动事件对象失败

蓝色的blue 发布于 2015-02-10 17:35, 614 次点击
#include<iostream>
#include<windows.h>
using std::cout;
DWORD WINAPI fun1(LPVOID lpParameter);
DWORD WINAPI fun2(LPVOID lpParameter);
int ticket=100;
//HANDLE hMutex;
HANDLE g_hEvent;
int main()
{
    HANDLE hTreadl,hTread2;
    g_hEvent=CreateEvent(NULL,FALSE,FALSE,"tickets");
    if(g_hEvent)
    {
        if(ERROR_ALREADY_EXISTS==GetLastError())
        {
            cout<<"only one instance can run\n";
            return 0;
        }
    }
    hTreadl=CreateThread(NULL,0,fun1,NULL,0,NULL);
    hTread2=CreateThread(NULL,0,fun2,NULL,0,NULL);
    CloseHandle(hTreadl);
    CloseHandle(hTread2);
    Sleep(4000);
    CloseHandle(g_hEvent);
    return 0;
}
DWORD WINAPI fun1(LPVOID lpParameter)
{
    while(1)
    {
        WaitForSingleObject(g_hEvent,INFINITE);
        if(ticket>0)
        {
            cout<<"thread1 sell ticket:"<<ticket--<<std::endl;
            SetEvent(g_hEvent);
        }
        else
        {
            SetEvent(g_hEvent);
            break;
        }
        //ReleaseMutex(hMutex);
    }
    return 0;
}
DWORD WINAPI fun2(LPVOID lpParameter)
{
    while(1)
    {
        WaitForSingleObject(g_hEvent,INFINITE);
        if(ticket>0)
        {
            cout<<"thread2 sell ticket:"<<ticket--<<std::endl;
            SetEvent(g_hEvent);
        }
        else
        {
            SetEvent(g_hEvent);
            break;
        }
        //ReleaseMutex(hMutex);
    }
    return 0;
}
//
//
//大神能看看我的代码 为什么执行到WaitForSingleObject(g_hEvent,INFINITE);不往下执行了???
5 回复
#2
天使梦魔2015-02-10 22:04
转的
一些需要注意的问题:


线程函数:

DWORD WINAPI ThreadProc(
      while ( ! bTerminate)
       {
          //  从一个链表中读取信息并且插入到CListCtrl中
          //  CListCtrl的句柄是通过线程参数传递进来的
          for (;;)
          {
            ReadInfoFromList();
            InsertToCListCtrl();
         }
     }
 }
 

主线程中使用CreateThread启动线程。
 当想终止子线程时,在主线程中:
bTerminate = TRUE;
 WaitForSingleObject(threadHandle, INFINITE);
可是,以运行到WaitForSingleObject,子线程就Crash了。
 为什么呢?
 问题原因:
 后来我终于在InsertItem的反汇编中发现了如下的代码
call dword ptr [__imp__SendMessageA@16 (7C141B54h)]
可见,InsertItem是必须借助消息循环来完成任务的。如果我们在主线程中WaitForSingleObject了,必然导致主线程阻塞,也就导致了消息循环的阻塞,最终导致工作线程Crash掉了*_*
解决方案:
 为了解决在主线程中Wait的问题,微软专门设计了一个函数MsgWaitForMultipleObjects,这个函数即可以等待信号 (thread,event,mutex等等),也可以等待消息(MSG)。即不论有信号被激发或者有消息到来,此函数都可以返回。呵呵,那么我的解决办 法也就出来了。
 将上面的WaitForSingleObject用下面的代码替换:


while (TRUE)
  {
     DWORD result ;
     MSG msg ;

     result  =  MsgWaitForMultipleObjects( 1 ,  & readThreadHandle,
         FALSE, INFINITE, QS_ALLINPUT);

      if  (result  ==  (WAIT_OBJECT_0))
       {
          break ;
     }  
      else
       {
         PeekMessage( & msg, NULL,  0 ,  0 , PM_REMOVE);
         DispatchMessage( & msg);
     }  
 }  

#3
蓝色的blue2015-02-13 20:47
回复 2楼 天使梦魔
课时线程函数1不应该接受不到信号的,,也就是那个wait 的接受函数不应该阻塞的
#4
蓝色的blue2015-02-13 20:50
回复 2楼 天使梦魔
大神你可以把代码复制下来运行看看。。那个线程函数总是不能执行
#5
天使梦魔2015-02-16 13:03
HANDLECreateEvent(
LPSECURITY_ATTRIBUTESlpEventAttributes,// 安全属性
BOOLbManualReset,// 复位方式
BOOLbInitialState,// 初始状态
LPCTSTRlpName // 对象名称


你特么在整我是吧,上来就调成无信号的,自己看看第3个参数是什么,前期调成false需要再次调用ResetEvent()手动重置。你要么一出来设置成true
#6
蓝色的blue2015-02-17 23:07
回复 5楼 天使梦魔
抱歉抱歉 ,,我是新手,,祝你新年快乐
1