スレッドロックの概念関数EnterCriticalSectionとLeaveCriticalSectionの使い方

20039 ワード

変換元:http://www.itcodeworld.com/?p=105
構造CRITICALの使用SECTIONはヘッダファイル#include"afxmt.h"を追加する必要があります
グローバルなロックCRITICALを定義します.SECTIONのインスタンスと静的グローバル変数

  
    
CRITICAL_SECTION cs; //
static int n_AddValue = 0 ; // n_AddValue

2つのスレッド関数を作成します.コードは次のように実装されます.


コード#コード#

   
     
//
UINT FirstThread(LPVOID lParam)
{
EnterCriticalSection(
& cs); // , LeaveCriticalSection
for ( int i = 0 ; i < 10 ; i ++ ){
n_AddValue
++ ;
cout
<< " n_AddValue in FirstThread is " << n_AddValue << endl;
}
LeaveCriticalSection(
& cs); // EnterCriticalSection ,
return 0 ;
}
//
UINT SecondThread(LPVOID lParam)
{
EnterCriticalSection(
& cs); //
for ( int i = 0 ; i < 10 ; i ++ ){
n_AddValue
++ ;
cout
<< " n_AddValue in SecondThread is " << n_AddValue << endl;

}
LeaveCriticalSection(
& cs); //
return 0 ;
}

 
メイン関数に次のコードを追加


コード#コード#

   
     
int _tmain( int argc, TCHAR * argv[], TCHAR * envp[])
{
int nRetCode = 0 ;

// MFC
if ( ! AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0 ))
{
// TODO:
_tprintf(_T( " : MFC
" ));
nRetCode
= 1 ;
}
else
{
InitializeCriticalSection(
& cs); // CRITICAL_SECTION

CWinThread
* pFirstThread, * pSecondThread; // AfxBeginThread CWinThread

pFirstThread
= AfxBeginThread(FirstThread,LPVOID(NULL)); //
pSecondThread = AfxBeginThread(SecondThread,LPVOID(NULL)); //

HANDLE hThreadHandle[
2 ]; //
hThreadHandle[ 0 ] = pFirstThread -> m_hThread;
hThreadHandle[
1 ] = pSecondThread -> m_hThread;

//
WaitForMultipleObjects( 2 ,hThreadHandle,TRUE,INFINITE);
}

return nRetCode;
}

 
出力:
n_AddValue in FirstThread is 1n_AddValue in FirstThread is 2n_AddValue in FirstThread is 3n_AddValue in FirstThread is 4n_AddValue in FirstThread is 5n_AddValue in FirstThread is 6n_AddValue in FirstThread is 7n_AddValue in FirstThread is 8n_AddValue in FirstThread is 9n_AddValue in FirstThread is 10n_AddValue in SecondThread is 11n_AddValue in SecondThread is 12n_AddValue in SecondThread is 13n_AddValue in SecondThread is 14n_AddValue in SecondThread is 15n_AddValue in SecondThread is 16n_AddValue in SecondThread is 17n_AddValue in SecondThread is 18n_AddValue in SecondThread is 19n_AddValue in SecondThread is 20
2つのスレッド関数のEnterCriticalSectionとLeaveCriticalSectionの位置をforループに移動すると、スレッドの実行順序が変更され、次のように出力が変更されます.
 


コード#コード#

   
     
//
UINT FirstThread(LPVOID lParam)
{

for ( int i = 0 ; i < 10 ; i ++ ){
EnterCriticalSection(
& cs); // for
n_AddValue ++ ;
cout
<< " n_AddValue in FirstThread is " << n_AddValue << endl;
LeaveCriticalSection(
& cs); //
}
return 0 ;
}

//
UINT SecondThread(LPVOID lParam)
{

for ( int i = 0 ; i < 10 ; i ++ ){
EnterCriticalSection(
& cs); //
n_AddValue ++ ;
cout
<< " n_AddValue in SecondThread is " << n_AddValue << endl;
LeaveCriticalSection(
& cs); //
}
return 0 ;
}

 
他のコードは変わりません.出力の結果は次のとおりです.
n_AddValue in FirstThread is 1n_AddValue in SecondThread is 2n_AddValue in FirstThread is 3n_AddValue in SecondThread is 4n_AddValue in FirstThread is 5n_AddValue in SecondThread is 6n_AddValue in FirstThread is 7n_AddValue in SecondThread is 8n_AddValue in FirstThread is 9n_AddValue in SecondThread is 10n_AddValue in FirstThread is 11n_AddValue in SecondThread is 12n_AddValue in FirstThread is 13n_AddValue in SecondThread is 14n_AddValue in FirstThread is 15n_AddValue in SecondThread is 16n_AddValue in FirstThread is 17n_AddValue in SecondThread is 18n_AddValue in FirstThread is 19n_AddValue in SecondThread is 20
個人的には、関数EnterCriticalSectionとLeaveCriticalSectionの間のコード実行プロセスは、他のスレッドによって干渉されないか、または他のスレッドのコード実行が許可されないと考えられています.これにより、1つのグローバル変数が2つのスレッドで同時に動作する可能性を効果的に防止することができる.