Win32的多線程鎖主要有四種
臨界區:critical_section
互斥:mutex
信號:semophore
事件:event
其中臨界區不能跨進程,互斥,信號,事件屬於內核對象,都可以跨進程
跟臨界區相關的API
VOIDInitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection ) 創建臨界區
VOID DeleteCriticalSection(LPCRITICAL_SECTIONlpCriticalSection ) 刪除臨界區
進入臨界區,有兩個函數
VOIDEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection ) 相當於申請加鎖,如果該臨界區正被其他線程使用則該函數會等待到其他線程釋放
BOOL TryEnterCriticalSection(LPCRITICAL_SECTIONlpCriticalSection )相當於申請加鎖,和EnterCriticalSection不同如果該臨界區正被其他線程使用則該函數會立即返回 FALSE,而不會等待
VOID LeaveCriticalSection(LPCRITICAL_SECTIONlpCriticalSection ) 退出臨界區,相當於申請解鎖
寫個程序跑一下
#include <iostream>
#include <process.h>
#include <windows.h>
using namespace std;
CRITICAL_SECTION g_cs;
int sum;
unsigned int __stdcall ThreadFunc(void *arg)
{
int num = (int)arg;
for(int i = 0; i < 8; i++)
{
EnterCriticalSection(&g_cs);
sum++;
cout<<"thread"<<num<<" sum is "<<sum<<endl;
Sleep(10);
LeaveCriticalSection(&g_cs);
}
return 0;
}
int main(void)
{
HANDLE handle[2];
InitializeCriticalSection(&g_cs); //
handle[0] = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, (void*)1, 0, NULL);
handle[1] = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, (void*)2, 0, NULL);
WaitForMultipleObjects(2, handle, TRUE, INFINITE);
CloseHandle(handle[0]);
CloseHandle(handle[1]);
DeleteCriticalSection(&g_cs);
return 0;
}
在這裏創建多線程用的是_beginthreadex,並沒有使用win32的api的CreateThread函數,事實上不建議使用CreateThread函數,涉及到c語言函數的重入問題。在此或者使用_beginthread函數,不過_beginthreadex函數跟MFC的函數AfxBeginThread的參數類似。
_beginthreadex和_beginthread函數有一些不同,具體的參照MSDN,需要注意的是_beginthread和_beginthreadex,在線程函數正常結束後都會自動調用_endthread和_endthreadex函數,_endthread會close掉線程的handle,_endthreadex則不會。線程函數的調用方式也有不同,_beginthread是_cdecl方式,_beginthreadex是_stdcall方式。