c++におけるSetEventとResetEventの使用
イベントイベント(Event)はWIN 32が提供する最も柔軟なスレッド間同期方式であり、イベントは励起状態(signaled or true)または非励起状態(unsignal or false)であってもよい.状態遷移方式によっては,(1)手動設定,(1)このオブジェクトはプログラムによる手動設定のみ可能であり,そのイベントまたはイベント発生が必要な場合にはSetEventおよびResetEventを用いて設定する.(2)自動リカバリ:イベントが発生して処理されると、自動的にイベントがない状態にリカバリされ、再設定する必要はありません.イベントを作成する関数のプロトタイプは次のとおりです.
HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,//SECURITY_ATTRIBUTES構造ポインタは、NULL BOOL bManualReset、//手動/自動//TRUE:WaitForSingleObject後にResetEventクリア信号//FALSE:WaitForSingleObject後、システムはイベント信号BOOL bInitialStateを自動的にクリアし、//初期状態LPCTSTR lpName//イベント名);
「イベント」メカニズムを使用するには、(1)プロセス間でイベントにアクセスする場合は、イベントに名前を付ける必要があります.イベントに名前を付けるときは、システムネーミングスペース内の他のグローバルネーミングオブジェクトと衝突しないように注意してください.(2)イベントが自動的に復元されるかどうか.(3)イベントの初期状態設定.
次のコードを見てください.
このコードは,前回のUINT型のループ変数としての不確実性に関する問題に続き,臨界領域制御グローバル変数へのアクセスを加えたものである.
ここで説明するのは、SetEventとResetEventの使用です.これは、注釈5と注釈6を参照してください.
備考5箇所:
CreateEventの2番目のパラメータは、ResetEventを手動で呼び出す必要があるかどうかを決定します.TRUEの場合、手動で呼び出す必要がありますが、呼び出さなければどうなりますか.呼び出さないと、イベントは常に信号状態、すなわち注釈6にあります.FALSEの場合、手動で呼び出す必要はありません.呼び出す必要はありません.効果は同じです.ResetEventを
WaitForSingleObjectの前でも良い方法です.
転載はオリジナルリンクを明記してください:http://blog.csdn.net/wujunokay/article/details/12272581
HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,//SECURITY_ATTRIBUTES構造ポインタは、NULL BOOL bManualReset、//手動/自動//TRUE:WaitForSingleObject後にResetEventクリア信号//FALSE:WaitForSingleObject後、システムはイベント信号BOOL bInitialStateを自動的にクリアし、//初期状態LPCTSTR lpName//イベント名);
「イベント」メカニズムを使用するには、(1)プロセス間でイベントにアクセスする場合は、イベントに名前を付ける必要があります.イベントに名前を付けるときは、システムネーミングスペース内の他のグローバルネーミングオブジェクトと衝突しないように注意してください.(2)イベントが自動的に復元されるかどうか.(3)イベントの初期状態設定.
次のコードを見てください.
DWORD WINAPI ThreadProc(LPVOID lpParam);
DWORD WINAPI ThreadProc2(LPVOID lpParam);
DWORD g_dwThreadID;
DWORD g_dwThreadID2;
UINT g_nTickets = 300; //int g_nTickets = 300; // 1
HANDLE g_hEvent = NULL;
HANDLE g_hEvent1 = NULL;
HANDLE g_hEvent2 = NULL;
CRITICAL_SECTION g_cs;
int ThreadCout = 0;
int main()
{
cout << "Main thread is running." << endl;
InitializeCriticalSection(&g_cs);//
HANDLE hHandle = CreateThread(NULL, 0, ThreadProc, NULL, 0, &g_dwThreadID);
ThreadCout++;
HANDLE hHandle2 = CreateThread(NULL, 0, ThreadProc2, NULL, 0, &g_dwThreadID2);
ThreadCout++;
//g_hEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
g_hEvent1 = CreateEvent(NULL, FALSE, TRUE, NULL); // 5:g_hEvent1 = CreateEvent(NULL, TRUE, TRUE, NULL);
g_hEvent2 = CreateEvent(NULL, FALSE, TRUE, NULL); // 5:g_hEvent2 = CreateEvent(NULL, TRUE, TRUE, NULL);
ResetEvent(g_hEvent1);
ResetEvent(g_hEvent2);
SetEvent(g_hEvent1);
while (TRUE)
{
EnterCriticalSection(&g_cs);
int nCount = ThreadCout;
LeaveCriticalSection(&g_cs);
if (nCount == 0)
{
cout << "Main thread is break." << endl;
break;
}
}
Sleep(1000); // 4
CloseHandle(hHandle);
CloseHandle(hHandle2);
DeleteCriticalSection(&g_cs);
cout << "Main thread is end." << endl;
system("pause");
return 0;
}
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
// cout << "No." << g_dwThreadID << " thread is running." << endl;
while (TRUE)
{
WaitForSingleObject(g_hEvent1, INFINITE);
cout << "No.1 " << g_dwThreadID << " thread is running." << endl;
EnterCriticalSection(&g_cs);
int temp= g_nTickets;
LeaveCriticalSection(&g_cs);
cout << "No.1 " << g_dwThreadID << " thread is temp." << endl;
if (temp > 0)
{
Sleep(10); //Sleep(1000) // 2
cout << "No.1-" << g_dwThreadID << " sell ticket : " << temp << endl;
EnterCriticalSection(&g_cs);
g_nTickets--;
LeaveCriticalSection(&g_cs);
SetEvent(g_hEvent2);
//ResetEvent(g_hEvent1);// 6
}
else
{
cout << "No.1- break" << endl;
//ResetEvent(g_hEvent1);// 6
SetEvent(g_hEvent2);// ThreadProc2 // 3
break;
}
}
EnterCriticalSection(&g_cs);
ThreadCout--;
LeaveCriticalSection(&g_cs);
cout << "No.1- end" << endl;
return 0;
}
DWORD WINAPI ThreadProc2(LPVOID lpParam)
{
//
while (TRUE)
{
WaitForSingleObject(g_hEvent2, INFINITE);
cout << "No.2 " << g_dwThreadID2 << " thread is running." << endl;
EnterCriticalSection(&g_cs);
int temp= g_nTickets;
LeaveCriticalSection(&g_cs);
if (temp > 0)
{
Sleep(10); //Sleep(1000) // 2
cout << "No.2-" << g_dwThreadID2 << " sell ticket : " << temp << endl;
EnterCriticalSection(&g_cs);
g_nTickets--;
LeaveCriticalSection(&g_cs);
SetEvent(g_hEvent1);
//ResetEvent(g_hEvent2);// 6
}
else
{
cout << "No.2- break" << endl;
//ResetEvent(g_hEvent2);// 6
SetEvent(g_hEvent1);// , ThreadProc // 3
break;
}
}
EnterCriticalSection(&g_cs);
ThreadCout--;
LeaveCriticalSection(&g_cs);
cout << "No.2- end" << endl;
return 0;
}
このコードは,前回のUINT型のループ変数としての不確実性に関する問題に続き,臨界領域制御グローバル変数へのアクセスを加えたものである.
ここで説明するのは、SetEventとResetEventの使用です.これは、注釈5と注釈6を参照してください.
備考5箇所:
CreateEventの2番目のパラメータは、ResetEventを手動で呼び出す必要があるかどうかを決定します.TRUEの場合、手動で呼び出す必要がありますが、呼び出さなければどうなりますか.呼び出さないと、イベントは常に信号状態、すなわち注釈6にあります.FALSEの場合、手動で呼び出す必要はありません.呼び出す必要はありません.効果は同じです.ResetEventを
WaitForSingleObjectの前でも良い方法です.
転載はオリジナルリンクを明記してください:http://blog.csdn.net/wujunokay/article/details/12272581