首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

一个Event,多个响应的有关问题

2012-02-26 
一个Event,多个响应的问题先上代码:C/C++ codeHANDLE g_hEventNULLBOOLg_RunTRUETCHARg_buf[0x100]{0

一个Event,多个响应的问题
先上代码:

C/C++ code
HANDLE g_hEvent=NULL;BOOL   g_Run=TRUE;TCHAR  g_buf[0x100]={0};unsigned int WINAPI EvenThread(void *pVoid){    OutputDebugString(TEXT("start"));    while(g_Run)    {        WaitForSingleObject(g_hEvent,INFINITE);        if(g_Run)        {            OutputDebugString(g_buf);        }    }    OutputDebugString(TEXT("end"));    return 0;}//Start Eventvoid CTestSTLDlg::OnBnClickedButton12(){    if(g_hEvent==NULL)    {        g_Run=TRUE;        g_hEvent=CreateEvent(NULL,FALSE,FALSE,TEXT("myTestEvent"));//自动重置信号        _beginthreadex(NULL,0,EvenThread,NULL,0,NULL);    }    else    {        OnBnClickedButton13();    }}//Stop Eventvoid CTestSTLDlg::OnBnClickedButton13(){    g_Run=FALSE;    SetEvent(g_hEvent);    CloseHandle(g_hEvent);    g_hEvent=NULL;}//Notify Eventvoid CTestSTLDlg::OnBnClickedButton14(){    SetEvent(g_hEvent);    GetDlgItemText(IDC_EDIT4,g_buf,0x100);}


这是一个MFC程序.
我生成的exe,然后运行了三个.
并且都调用了OnBnClickedButton12,即会在三个进程中都创建一个线程:EvenThread.

这时后,我点击任意一个exe中的OnBnClickedButton14()通知按键,都只有一个线程中的Event变成有信号状态,执行读取
g_buf的操作,因为WaitForSingleObject后变自动变为无信号,其它线程就无法再响应了.
也许你会说:设成人工重置信号不就行了,这样当然是可以都响应,但是这样它却会不停的响应的,而我只想响应一次就继续等待下一次通知.

所以想请教大家:
有没有办法,能让这些线程都响应这个事件,且只响应一次.

[解决办法]
CreateEvent每次创建的时候用一个单独的名字,这样就不会重复了
[解决办法]
用手动重置Event,线程唤醒执行了就退出
[解决办法]
这是一个MFC程序.
我生成的exe,然后运行了三个.
并且都调用了OnBnClickedButton12,即会在三个进程中都创建一个线程:EvenThread.
-----------
你三个进程直接需要通讯?不需要的话,你CreateEvent创建事件对象的时候指定名称为NULL就可以了
[解决办法]
方法1、人工重置 + PulseEvent,但微软说她这个孩子不是很靠谱。
方法2、试试SignalObjectAndWait,(微软新生的,原子的,我也没用过)
[解决办法]
没有很简单的办法,一个可靠的办法用共享内存,记住所有启动进程的pid,然后创建event的时候event名字用myTestEvent+pid,通知的时候每个pid对应的event都setevent一次。
这样简单可靠,不用考虑太多同步问题和进程崩溃的情况
[解决办法]
首先把命名事件改成手动状态,再定义一个全局量,给每个线程处理事件赋不同的权重,在线程内处理完后达到权重总和就恢复事件,没达到就说明有人还没处理就不要改变事件状态。

唉,现在的年轻人啊。
[解决办法]
使用带计数的Semaphore配合WaitForSingleObject。基本就能满足你的需求。

C/C++ code
hSemaphore = CreateSemaphore(     NULL,   // default security attributes    0,   // initial count    cThreadCount,   // maximum count    NULL);  // unnamed semaphore
[解决办法]
方法1、人工重置 + PulseEvent,但微软说她这个孩子不是很靠谱。
方法2、试试SignalObjectAndWait,(微软新生的,原子的,我也没用过)

都不好,你这个我问题的确有点难搞
人工重置和自动重置事件都不可以实现
你可以在进程启动的时候,注册消息,通过自动重置事件发送消息,三个进程都可以执行
这个是最好的了

热点排行