用内核对象进行线程同步——事件内核对象

来源:互联网 发布:linux创建多层文件夹 编辑:程序博客网 时间:2024/06/05 22:57

事件内核对象
1. 手动重置事件:当一个手动重置事件被触发的时候,所有等待该事件的线程都变为可调度状态。所以要注意此时所有的线程都只能以只读的方式来访问内存,这也是多个线程能够同时运行的唯一原因
2. 自动重置事件:当一个自动重置事件被触发的时候,只有一个等待该事件的线程都变为可调度状态(当线程成功等到事件触发的时候,会自动的把事件重置为未触发状态),其余的继续等待。

创建一个事件内核对象

HANDLE CreateEvent(     LPSECURITY_ATTRIBUTES lpEventAttributes,     BOOL bManualReset,  //TRUE:手动重置事件; FALSE:自动重置事件     BOOL bInitialState, //TRUE:事件初始化为触发状态; FALSE:事件初始化为未触发状态     LPCSTR lpName    );

打开一个事件内核对象
其他进程中的线程要访问该事件对象可以调用OpenEvent

HANDLE OpenEvent(     DWORD dwDesiredAccess,     BOOL bInheritHandle,     LPCSTR lpName    );

改变事件触发状态

BOOL SetEvent(HANDLE hEvent);    // 把事件变为触发状态BOOL ResetEvent(HANDLE hEvent);  // 把事件变为未触发状态

关闭事件对象
当不在需要事件对象时,要调用CloseHandle来将它关闭

BOOL CloseHandle(HANDLE hObject);

手动重置事件例子

#include "stdafx.h"#include <windows.h>#include <process.h>#include <iostream>using namespace std;int g_x = 0;HANDLE g_hEvent;// 线程只读UINT WINAPI ThreadFunc1(PVOID pArguments){    WaitForSingleObject(g_hEvent, INFINITE);    cout << "ThreadFunc1.." << endl;    _endthreadex(0);    return 0;}// 线程只读UINT WINAPI ThreadFunc2(PVOID pArguments){    WaitForSingleObject(g_hEvent, INFINITE);    cout << "ThreadFunc2.." << endl;    _endthreadex(0);    return 0;}// 线程只读UINT WINAPI ThreadFunc3(PVOID pArguments){    WaitForSingleObject(g_hEvent, INFINITE);    cout << "ThreadFunc3.." << endl;    _endthreadex(0);    return 0;}int _tmain(int argc, _TCHAR* argv[]){    HANDLE   handle[3];    unsigned    unThreadID[3];    cout << "g_x initial value: " << g_x << endl;    // 创建一个未触发的手动重置事件    g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);    handle[0] = (HANDLE)_beginthreadex(NULL,        0,        &ThreadFunc1,        NULL,        0,        &unThreadID[0]);    handle[1] = (HANDLE)_beginthreadex(NULL,        0,        &ThreadFunc2,        NULL,        0,        &unThreadID[1]);    handle[2] = (HANDLE)_beginthreadex(NULL,        0,        &ThreadFunc3,        NULL,        0,        &unThreadID[2]);    g_x = 100;    // 给g_x赋值后调用SetEvent触发事件,此时三个线程都变成可调度状态,获得CPU时间。    // 但是注意此时所有的三个线程都只能以只读的方式来访问内存,这也是三个线程能够同时运行的唯一原因    SetEvent(g_hEvent);    WaitForMultipleObjects(3, handle, TRUE, INFINITE);    CloseHandle(g_hEvent);    g_hEvent = NULL;    cout << "g_x Final value: " << g_x << endl;    getchar();    return 0;}

自动重置事件例子

// ThreadDemo.cpp : コンソール アプリケーションのエントリ ポイントを定義します。//#include "stdafx.h"#include <windows.h>          #include <process.h> #include <iostream>using namespace std;int g_x = 0;HANDLE g_hEvent;// 写入线程UINT WINAPI ThreadFunc1(PVOID pArguments){    // 当线程成功等到事件对象触发的时候,自动重置事件会把事件对象重置为为触发状态,锁定资源,独占内存    WaitForSingleObject(g_hEvent, INFINITE);    int n = 0;    while (n < 5)    {        g_x += n;        n++;        cout << "ThreadFunc1.." << endl;    }    // 当线程结束,要释放资源,故把事件对象重置为触发状态,以便等待该资源的其他线程访问    SetEvent(g_hEvent);    _endthreadex(0);    return 0;}// 读线程UINT WINAPI ThreadFunc2(PVOID pArguments){    WaitForSingleObject(g_hEvent, INFINITE);    cout << "ThreadFunc2.." << endl;    SetEvent(g_hEvent);    _endthreadex(0);    return 0;}// 写入线程UINT WINAPI ThreadFunc3(PVOID pArguments){    WaitForSingleObject(g_hEvent, INFINITE);    int n = 0;    while (n < 5)    {        g_x += n;        n++;        cout << "ThreadFunc3.." << endl;    }    SetEvent(g_hEvent);    _endthreadex(0);    return 0;}int _tmain(int argc, _TCHAR* argv[]){    HANDLE   handle[3];    unsigned    unThreadID[3];    cout << "g_x initial value: " << g_x << endl;    // 创建一个未触发的自动动重置事件    g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);    handle[0] = (HANDLE)_beginthreadex(NULL,        0,        &ThreadFunc1,        NULL,        0,        &unThreadID[0]);    handle[1] = (HANDLE)_beginthreadex(NULL,        0,        &ThreadFunc2,        NULL,        0,        &unThreadID[1]);    handle[2] = (HANDLE)_beginthreadex(NULL,        0,        &ThreadFunc3,        NULL,        0,        &unThreadID[2]);    g_x = 100;    // 由于事件初始化为未触发状态,所以在线程准备完毕后,调用SetEvent触发事件,此时只有一个线程都变成可调度状态,独占资源。其他线程继续等待    // 由于等待自动重置事件对象的线程是独占资源,故这些线程可读可写    SetEvent(g_hEvent);    WaitForMultipleObjects(3, handle, TRUE, INFINITE);    CloseHandle(g_hEvent);    g_hEvent = NULL;    cout << "g_x Final value: " << g_x << endl;    getchar();    return 0;}
原创粉丝点击