通过Event事件正确结束线程

  
步骤:
1. 首先声明一个全局的Event对象
       HANDLE hRequestExitEvent = FALSE;
2. 在主线程中创建这个Event对象
       hRequestExitEvent = CreateEvent(NULL, TRUE, false, NULL);
       注意:此处的第三个参数应该使用false,因为如果使用true在事件创建开始就是处于
    激发状态,这样就立刻结束线程了,所以此处应该使用false作参数
3. 在线程函数中使用如下语句来不断探测Event对象的状态并确定是否退出线程
       WaitForSingleObject(hRequestExitEvent, 0)
       注意:此处的此处的第二个参数为0,这里使用了WaitForSingleObject()函数一个很重
要的用途,设定这个参数为0,是你能够检查handle的状态并立刻返回,没有片刻停留,
如果handle已经备妥,这个函数会成功并传回WAIT_OBJET_0,否则这个函数立刻传
回WAIT_TIMEOUT。
4. 在主线程中需要结束该线程的地方调用如下语句设置Event对象为激发状态
       SetEvent(hRequestExitEvent);
       这样便可安全的结束一个线程
 
参考代码:
说明:该实例代码参考《Win32 多线程程序设计(候捷译)》中的THRDTERM程序,该程序创建两个线程,周期性地检查一个Event对象,以决定要不要结束自己。
#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#include "MtVerify.h"
 
DWORD WINAPI ThreadFunc(LPVOID);
 
HANDLE hRequestExitEvent = FALSE; //设置全局EVENT对象
 
int main()
{
    HANDLE hThreads[2];
    DWORD dwThreadId;
    DWORD dwExitCode = 0;
    int i;
 
    hRequestExitEvent = CreateEvent(
        NULL, TRUE, false, NULL);   // 创建Event对象
 
    for (i=0; i<2; i++)
        MTVERIFY( hThreads[i] = CreateThread(NULL,
            0,
            ThreadFunc,
            (LPVOID)i,
            0,
            &dwThreadId )
        );
 
    // Wait around for awhile, make
    // sure the thread is running.
    Sleep(1000);
 
    SetEvent(hRequestExitEvent); //设置Event对象为激发状态,结束线程
      
WaitForMultipleObjects(2, hThreads, TRUE, INFINITE); // 等待两个线程都成为激发状
态,可以保证线程都已安全地离开。
 
       printf("1234/n");
 
    for (i=0; i<2; i++)
        MTVERIFY( CloseHandle(hThreads[i]) );
 
    return EXIT_SUCCESS;
}
 
 
DWORD WINAPI ThreadFunc(LPVOID p)
{
    int i;
    int inside = 0;
 
    UNREFERENCED_PARAMETER(p);
 
    /* Seed the random-number generator */
    srand( (unsigned)time( NULL ) );
 
    for (i=0; i<1000000; i++)
    {
        double x = (double)(rand())/RAND_MAX;
        double y = (double)(rand())/RAND_MAX;
        if ( (x*x + y*y) <= 1.0 )
            inside++;
        if (WaitForSingleObject(hRequestExitEvent, 0) != WAIT_TIMEOUT) // 判断Event对
           象是否为激发状态,从而决定是否退出
        {
            printf("Received request to terminate/n");
            return (DWORD)-1;
        }
    }
    printf("PI = %.4g/n", (double)inside / i * 4);
    return 0;
}
原文地址:https://www.cnblogs.com/zhangyunlin/p/6168011.html