說說win32多線程鎖之臨界區

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方式。





發佈了34 篇原創文章 · 獲贊 9 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章