Windows編程-- 使用者方式中線程的同步—關鍵程式碼片段(臨界區)

來源:互聯網
上載者:User

可以從例子學習,更好的掌握

 

#include <windows.h>                                      
#include <iostream.h>
//兩個線程的聲明
DWORD WINAPI Fun1Proc(LPVOID lpParameter);
DWORD WINAPI Fun2Proc(LPVOID lpParameter);

int tickets = 100;
CRITICAL_SECTION g_cs; //定義一個臨界區

int main()
{
HANDLE hThread1;
HANDLE hThread2;
hThread1=CreateThread(NULL,0, Fun1Proc, NULL,0, NULL);
hThread2=CreateThread(NULL,0, Fun2Proc, NULL,0, NULL);
CloseHandle(hThread1);
CloseHandle(hThread2);

InitializeCriticalSection(&g_cs); //初始化臨界區
Sleep(4000);

DeleteCriticalSection(&g_cs); //當臨界區裡沒有資源時釋放掉臨界區(可以這樣說嗎)???

return 0;
}


DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{


while (TRUE)
{
EnterCriticalSection(&g_cs); //該線程進入臨界區
if (tickets > 0)
{
Sleep( 1);
cout<< "Thread1 sell tickets:"<< tickets-- << endl;
}
else
{
break;
}
LeaveCriticalSection(&g_cs); //退出臨界區
}

return0;
}


DWORD WINAPI Fun2Proc(LPVOID lpParameter)
{

while(TRUE)
{
EnterCriticalSection(&g_cs); //該線程進入臨界區
if(tickets > 0)
{
Sleep( 1);
cout<< "Thread2 sell tickets:"<< tickets-- << endl;
}
else
{
break;
}
LeaveCriticalSection(&g_cs); //退出臨界區
}
return 0;

}

 

 

 

 應該注意的:

1 關鍵程式碼片段(臨界區)工作在用 使用者方式下

2 關鍵程式碼片段(臨界區)是指一個小程式碼片段,在代碼夠執行前。它必須獨佔對某些資源的訪問權。

3 關鍵程式碼片段是工作在使用者方式下。同步速度較快,但在使用關鍵程式碼片段時,很容易進入死結狀態。因為在等待進入關鍵程式碼片段時無法設定逾時值。

4 線程死結 線程1擁有了臨界區對象A。等待臨界區對象B的擁有權。線程2擁有了臨界區對象B,等待臨界區對象A的擁有權,就造成了死結。

5 無法用它們對多個進程中的各個線程進行同步 

 

以下的例子就是進入了死結。 


#include <windows.h>                                      
#include <iostream.h>
//1、兩個線程的聲明
DWORD WINAPI Fun1Proc(LPVOID lpParameter);
DWORD WINAPI Fun2Proc(LPVOID lpParameter);

int tickets = 100;
CRITICAL_SECTION g_csA; //2、定義兩個臨界區
CRITICAL_SECTION g_csB;

int main()
{
HANDLE hThread1;
HANDLE hThread2;
hThread1=CreateThread(NULL,0, Fun1Proc, NULL,0, NULL);
hThread2=CreateThread(NULL,0, Fun2Proc, NULL,0, NULL);
CloseHandle(hThread1);
CloseHandle(hThread2);

InitializeCriticalSection(&g_csA); //3、初始化臨界區
InitializeCriticalSection(&g_csB);
Sleep(4000);

DeleteCriticalSection(&g_csA); //4、當臨界區裡沒有資源時釋放掉臨界區
DeleteCriticalSection(&g_csB);
return 0;
}


DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{

// 11、兩個臨界區和兩個線程會形成死機。線程在等待無法進入臨界區g_csB。線程在等待無法進入臨界區g_csA

while (TRUE)
{
EnterCriticalSection(&g_csA); //5、該線程進入臨界區g_csA
Sleep(1); //6、線程進入睡眠狀態 線程時間片斷結束線程開始
EnterCriticalSection(&g_csB); //9、線程進入臨界區g_csB,但是臨界區g_csB已被線程佔用故只能等待時間片斷交給線程
if (tickets > 0)
{
Sleep( 1);
cout<< "Thread1 sell tickets:"<< tickets-- << endl;
}
else
{
break;
}
LeaveCriticalSection(&g_csB); //退出臨界區
LeaveCriticalSection(&g_csA);
}

return 0;
}


DWORD WINAPI Fun2Proc(LPVOID lpParameter)
{

while(TRUE)
{
EnterCriticalSection(&g_csB); //7、線程進入臨界區g_csB
Sleep(1); //8、線程進入睡眠狀態線程時間片斷結束線程開始
EnterCriticalSection(&g_csA); //10、線程進入臨界區g_csA 但是臨界區g_csA已被線程佔用故只能等待時間片斷交給線程

if(tickets > 0)
{
Sleep( 1);
cout<< "Thread2 sell tickets:"<< tickets-- << endl;
}
else
{
break;
}
LeaveCriticalSection(&g_csA);
LeaveCriticalSection(&g_csB); //退出臨界區
}
return 0;
}

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.