日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

windows多线程同步--临界区

發布時間:2025/7/14 windows 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 windows多线程同步--临界区 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

推薦參考博客:秒殺多線程第五篇 經典線程同步 關鍵段CS

?

關于臨界區的觀念,一般操作系統書上面都有。

適用范圍:它只能同步一個進程中的線程,不能跨進程同步。一般用它來做單個進程內的代碼快同步,效率比較高

windows中與臨界區有關的結構是 CRITICAL_SECTION,關于該結構體的內部結構可參考here

使用時,主線程中要先初始化臨界區,最后要刪除臨界區,具體使用見下面代碼:

????????????????????????????????????????????????????????????????????????????? 本文地址

從一個例子來說明:假設有三個線程都需要使用打印機,我們可以把打印的代碼放到臨界區,這樣就可以保證每次只有一個線程在使用打印機。

?

#include<string>#include<iostream>#include<process.h>#include<windows.h>using namespace std;//定義一個臨界區CRITICAL_SECTION g_cs;//線程綁定的函數返回值和參數是確定的,而且一定要__stdcall unsigned __stdcall threadFun(void *param) {EnterCriticalSection(&g_cs);//進入臨界區,如果有其他線程則等待cout<<*(string *)(param)<<endl;LeaveCriticalSection(&g_cs);//退出臨界區,其他線程可以進來了return 1; }int main() {//初始化臨界區InitializeCriticalSection(&g_cs);HANDLE hth1, hth2, hth3;string s1 = "first", s2 = "second", s3 = "third";//創建線程hth1 = (HANDLE)_beginthreadex(NULL, 0, threadFun, &s1, 0, NULL);hth2 = (HANDLE)_beginthreadex(NULL, 0, threadFun, &s2, 0, NULL);hth3 = (HANDLE)_beginthreadex(NULL, 0, threadFun, &s3, 0, NULL);//等待子線程結束WaitForSingleObject(hth1, INFINITE);WaitForSingleObject(hth2, INFINITE);WaitForSingleObject(hth3, INFINITE);//一定要記得關閉線程句柄CloseHandle(hth1);CloseHandle(hth2);CloseHandle(hth3);//刪除臨界區DeleteCriticalSection(&g_cs); }

?

再看另外一個問題:編寫一個程序,開啟3個線程,這3個線程的ID分別為A、B、C,每個線程將自己的ID在屏幕上打印10遍,要求輸出結果必須按ABC的順序顯示;如:ABCABC….依次遞推, 仿照文章windows多線程同步--信號量中的代碼,我們把信號量替換成臨界區。

#include<string>#include<iostream>#include<process.h>#include<windows.h>using namespace std;//聲明3個臨界區 CRITICAL_SECTION g_cs1, g_cs2, g_cs3;//線程綁定的函數返回值和參數是確定的,而且一定要__stdcall unsigned __stdcall threadFunA(void *) {for(int i = 0; i < 10; i++){EnterCriticalSection(&g_cs1);//進入臨界區cout<<"A";LeaveCriticalSection(&g_cs2);//離開臨界區}return 1; } unsigned __stdcall threadFunB(void *) {for(int i = 0; i < 10; i++){EnterCriticalSection(&g_cs2);//進入臨界區cout<<"B";LeaveCriticalSection(&g_cs3);//離開臨界區}return 2; } unsigned __stdcall threadFunC(void *) {for(int i = 0; i < 10; i++){EnterCriticalSection(&g_cs3);//進入臨界區cout<<"C";LeaveCriticalSection(&g_cs1);//離開臨界區}return 3; }int main() {//初始化臨界區InitializeCriticalSection(&g_cs1);InitializeCriticalSection(&g_cs2);InitializeCriticalSection(&g_cs3);HANDLE hth1, hth2, hth3;//創建線程hth1 = (HANDLE)_beginthreadex(NULL, 0, threadFunA, NULL, 0, NULL);hth2 = (HANDLE)_beginthreadex(NULL, 0, threadFunB, NULL, 0, NULL);hth3 = (HANDLE)_beginthreadex(NULL, 0, threadFunC, NULL, 0, NULL);//等待子線程結束WaitForSingleObject(hth1, INFINITE);WaitForSingleObject(hth2, INFINITE);WaitForSingleObject(hth3, INFINITE);//一定要記得關閉線程句柄CloseHandle(hth1);CloseHandle(hth2);CloseHandle(hth3);//刪除臨界區DeleteCriticalSection(&g_cs1);DeleteCriticalSection(&g_cs2);DeleteCriticalSection(&g_cs3); }

?

為什么會這樣呢,因為臨界區有所有權的概念,即某個線程進入臨界區后,就擁有該臨界區的所有權,在他離開臨界區之前,他可以無限次的再次進入該臨界區,上例中線程A獲得臨界區1的所有權后,在線程C調用LeaveCriticalSection(&g_cs1)之前,A是可以無限次的進入臨界區1的。利用信號量之所以可以實現題目的要求,是因為信號量沒有所有權的概念,某個線程獲得信號量后,如果信號量的值為0,那么他一定要等到信號量被釋放時,才能再次獲得

關于臨界區的詳細解釋清參考秒殺多線程第五篇 經典線程同步 關鍵段CS

?

【版權聲明】轉載請注明出處:http://www.cnblogs.com/TenosDoIt/p/3601308.html

轉載于:https://www.cnblogs.com/TenosDoIt/p/3601308.html

總結

以上是生活随笔為你收集整理的windows多线程同步--临界区的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。