臨界區 CRITICAL_SECTION 死鎖問題解析

臨界區爲非內核對象,優點速度快,效率高缺點時間不好控制,有可能第二個線程永遠進不去 所以需要人爲的在執行完原子操作後sleep()把進入的線程的時間片讓出來
 和mutex相似,也是進去一個就關門了  唯一不同的是兩個函數的使用時候存在死鎖的問題,不是操作系統控制,時間片不好控制

 

下面爲死鎖問題復現
下面剛進去a 睡眠20ms 20ms是人爲放大的間隙那邊b進去了等到釋放a才能進去  而這邊要等到b釋放了 才能進去釋放a  所以互相等  一直等

#include "iostream"
#include "windows.h"
using namespace  std;

int g_iticket = 100;
unsigned long _stdcall bar(void*pramater);
unsigned long _stdcall bar1(void*pramater);

CRITICAL_SECTION csA; //臨界區 非內核讓出時間片的時候需要手動給一個sleep 工作在用戶區
CRITICAL_SECTION csB; 


int main(void)
{

    int inum1 = 1;
    int inum2 = 2;
    HANDLE thread1 = CreateThread(nullptr, 0, bar, &inum1, 0, nullptr);
    HANDLE thread2 = CreateThread(nullptr, 0, bar1, &inum2, 0, nullptr);
    InitializeCriticalSection(&csA);
    InitializeCriticalSection(&csB);

    if (thread1)
    {
        CloseHandle(thread1);
    }
    if (thread1)
    {
        CloseHandle(thread2);
    }
    Sleep(8000);

    return 0;
}

//臨界區死鎖問題示例
unsigned long _stdcall bar(void*pramater)
{
    int* inum = reinterpret_cast<int *>(pramater);
    while (true)
    {                                    
        EnterCriticalSection(&csA);
        //Sleep(20);                  //人爲放大這個間隙  將時間片讓出來, 這個線程拿到了csa 後在這裏睡20ms ,下面的線程拿到了csb,上面sleep結束後等csb,下面結束後又在等csa 就這樣形成一直等的死鎖問題
        EnterCriticalSection(&csB);

        if (g_iticket > 0)
        {
            
            cout << "#" << *inum << ":" << g_iticket-- << endl;
            LeaveCriticalSection(&csB);
            LeaveCriticalSection(&csA);
            Sleep(20);                //   
        }
        else
        {

            LeaveCriticalSection(&csB);
            LeaveCriticalSection(&csA);
            break;
        }

    }
    return 0;


}


unsigned long _stdcall bar1(void*pramater)
{
    int* inum = reinterpret_cast<int *>(pramater);
    while (true)
    {
        EnterCriticalSection(&csB);
        //Sleep(20);
        EnterCriticalSection(&csA);
        if (g_iticket > 0)
        {

            cout << "#" << *inum << ":" << g_iticket-- << endl;
            LeaveCriticalSection(&csA);
            LeaveCriticalSection(&csB);
            Sleep(20);//
        }
        else
        {

            LeaveCriticalSection(&csA);
            LeaveCriticalSection(&csB);
            break;
        }

    }
    return 0;


}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章