0、思考
關鍵代碼段可以解決線程間同步,進程間怎麼辦?
1、相關api
CreateEvent
CreateEventEx
SetEvent
ResetEvent
CloseHandle
OpenEvent
PulseEvent
WaitForSingleObject
WaitForMultipleObjects
2、寫在前面
特點:用於進程或線程間同步。
3、api說明
// 創建一個事件內核對象。
// lpEventAttributes:事件對象安全屬性;(通常爲NULL)
// bManualReset:手動重置(true),被觸發時正在等待該事件的所有線程都將被變成可調度狀態,需自行調用ResetEvent把事件變爲未通知狀態
(通常n個線程等待一個線程時,n個線程沒有順序關係和互斥關係則可使用手動重置);自動重置(true),被觸發時只有一個正在等待該事件的
線程會變爲可調度狀態,同時對象會自動重置爲未觸發狀態;(通常爲false)
// bInitialState:初始化爲觸發狀態(true),未觸發狀態(false);(通常爲false)
// lpName:有名事件對象,用於進程間同步。
WINBASEAPI
__out_opt
HANDLE
WINAPI
CreateEventA(
__in_opt LPSECURITY_ATTRIBUTES lpEventAttributes,
__in BOOL bManualReset,
__in BOOL bInitialState,
__in_opt LPCSTR lpName
);
WINBASEAPI
__out_opt
HANDLE
WINAPI
CreateEventW(
__in_opt LPSECURITY_ATTRIBUTES lpEventAttributes,
__in BOOL bManualReset,
__in BOOL bInitialState,
__in_opt LPCWSTR lpName
);
#ifdef UNICODE
#define CreateEvent CreateEventW
#else
#define CreateEvent CreateEventA
#endif // !UNICODE
// dwFlags:CREATE_EVENT_INITIAL_SET,觸發狀態;CREATE_EVENT_MANUAL_RESET,手動重置事件;(通常爲0)
// dwDesiredAccess:對事件有何訪問權限;(通常爲EVENT_MODIFY_STATE或者EVENT_ALL_ACCESS)
WINBASEAPI
__out_opt
HANDLE
WINAPI
CreateEventExA(
__in_opt LPSECURITY_ATTRIBUTES lpEventAttributes,
__in_opt LPCSTR lpName,
__in DWORD dwFlags,
__in DWORD dwDesiredAccess
);
WINBASEAPI
__out_opt
HANDLE
WINAPI
CreateEventExW(
__in_opt LPSECURITY_ATTRIBUTES lpEventAttributes,
__in_opt LPCWSTR lpName,
__in DWORD dwFlags,
__in DWORD dwDesiredAccess
);
#ifdef UNICODE
#define CreateEventEx CreateEventExW
#else
#define CreateEventEx CreateEventExA
#endif // !UNICODE
// 事件變成觸發狀態
WINBASEAPI
BOOL
WINAPI
SetEvent(
__in HANDLE hEvent
);
// 事件變成未觸發狀態
WINBASEAPI
BOOL
WINAPI
ResetEvent(
__in HANDLE hEvent
);
// 關閉一個打開的對象句柄。
WINBASEAPI
BOOL
WINAPI
CloseHandle(
__in HANDLE hObject
);
// 打開一個已經存在的命名事件對象。
// dwDesiredAccess:指定想要的訪問權限:EVENT_ALL_ACCESS請求對事件對象的完全訪問;EVENT_MODIFY_STATE允許使用;通常爲EVENT_ALL_ACCESS。
// bInheritHandle:是否希望子進程繼承事件對象的句柄,通常爲false。
// lpName:要打開的事件對象的名稱。
WINBASEAPI
__out_opt
HANDLE
WINAPI
OpenEventA(
__in DWORD dwDesiredAccess,
__in BOOL bInheritHandle,
__in LPCSTR lpName
);
WINBASEAPI
__out_opt
HANDLE
WINAPI
OpenEventW(
__in DWORD dwDesiredAccess,
__in BOOL bInheritHandle,
__in LPCWSTR lpName
);
#ifdef UNICODE
#define OpenEvent OpenEventW
#else
#define OpenEvent OpenEventA
#endif // !UNICODE
// 設置特定的事件對象爲有信號狀態,然後釋放相關的等待線程,再置時間對象爲無信號狀態。(ps:如果在一個線程PluseEvent()的時候,恰好沒有
線程處於等待狀態,那麼這個事件將丟失)(關注:SignalObjectAndWait)
WINBASEAPI
BOOL
WINAPI
PulseEvent(
__in HANDLE hEvent
);
4、C++封裝
#pragma once
#include <windows.h>
class ncEvent
{
public:
ncEvent (BOOL bManualReset = FALSE, BOOL bInitialState = FALSE, LPCTSTR lpName = NULL)
{
_event = CreateEvent (NULL, bManualReset, bInitialState, lpName);
}
~ncEvent ()
{
CloseHandle (_event);
}
BOOL set ()
{
return SetEvent (_event);
}
BOOL reset ()
{
return ResetEvent (_event);
}
operator HANDLE ()
{
return _event;
}
DWORD wait (DWORD timeout = INFINITE)
{
return WaitForSingleObject (_event, timeout);
}
private:
HANDLE _event;
};
5、順藤摸瓜
typedef struct _SECURITY_ATTRIBUTES {
DWORD nLength;
LPVOID lpSecurityDescriptor;
BOOL bInheritHandle;
} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
鳴謝