WIN32核心編程 - 線程操作(二) 同步互斥

  • 公開視頻 ->?鏈接點擊跳轉公開課程
  • 博客首頁 ->?鏈接點擊跳轉博客主頁

目錄

競態條件

CriticalSection

Mutex

CriticalSection & Mutex

Semaphore

Event


競態條件

  • 多線程環境下,當多個線程同時訪問或者修改同一個數據時,最終結果為線程執行的時許。

  • 如果沒有同步機制,會發生競態條件,可能導致數據不準確,或者程序發生異常等。

#include <iostream>
#include <windows.h>DWORD g_Num = 0;DWORD WINAPI WorkThread(LPVOID lp)
{for (size_t i = 0; i < 10000000; i++){//g_Num++;__asm LOCK INC [g_Num] }return 0;
}int main()
{HANDLE hThread[2] = { 0 };hThread[0] = CreateThread(NULL, 0, WorkThread, NULL, 0, NULL);hThread[1] = CreateThread(NULL, 0, WorkThread, NULL, 0, NULL);WaitForMultipleObjects(2, hThread, TRUE, -1);std::cout << g_Num << std::endl;return 0;
}

CriticalSection

#include <iostream>
#include <windows.h>DWORD g_Num = 0;
CRITICAL_SECTION cs = { 0 };DWORD WINAPI WorkThread(LPVOID lp)
{for (size_t i = 0; i < 1000000; i++){// 進入臨界區EnterCriticalSection(&cs);// TODOg_Num++;// 退出臨界區LeaveCriticalSection(&cs);}return 0;
}int main()
{HANDLE hThread[2] = { 0 };// 初始臨界區InitializeCriticalSection(&cs);hThread[0] = CreateThread(NULL, 0, WorkThread, NULL, 0, NULL);hThread[1] = CreateThread(NULL, 0, WorkThread, NULL, 0, NULL);WaitForMultipleObjects(2, hThread, TRUE, -1);std::cout << g_Num << std::endl;// 清理臨界區DeleteCriticalSection(&cs);return 0;
}

Mutex

  • 互斥體(Mutex),用于防止多個線程同時訪問或修改共享資源。

  • 同一時刻下只有一個線程可以擁有互斥體的所有權,如果一個線程擁有了互斥體的所有權,則其他請求該互斥體的線程將會被阻塞,直到互斥體權限釋放。

  • 創建互斥體 - CreateMutex

  • 請求互斥體 - WaitForSingleObject

  • 釋放互斥體 - ReleaseMutex

#include <iostream>
#include <windows.h>HANDLE hMutex = 0;
DWORD g_Num = 0;DWORD WINAPI WorkThread(LPVOID lp)
{for (size_t i = 0; i < 100000; i++){WaitForSingleObject(hMutex, INFINITE);g_Num++;ReleaseMutex(hMutex);}return 0;
}int main()
{hMutex = CreateMutex(NULL, FALSE, NULL); HANDLE hThread1 = CreateThread(NULL, 0, WorkThread, NULL, 0, NULL);HANDLE hThread2 = CreateThread(NULL, 0, WorkThread, NULL, 0, NULL);WaitForSingleObject(hThread1, INFINITE);WaitForSingleObject(hThread2, INFINITE);CloseHandle(hThread1);CloseHandle(hThread2);CloseHandle(hMutex);std::cout << g_Num << std::endl;return 0;
}

CriticalSection & Mutex

  • 臨界區

    • 共享資源的線程同步機制,臨界區在同一進程的線程之間提供了互斥訪問。

    • 每個線程在訪問共享資源之前必須先能夠進入臨界區,在訪問結束后離開臨界區,完成線程同步。

  • 互斥體

    • 線程同步機制,用來限制多個線程同時訪問共享資源。

    • 互斥體可以同步進程或者線程,且可以跨進程同步。
    • #include <iostream>
      #include <Windows.h>int main()
      {HANDLE hMutex = CreateMutex(NULL, FALSE, L"0xCC_Mutex");if (hMutex == NULL) return 0;if (GetLastError() == ERROR_ALREADY_EXISTS){MessageBox(NULL, L"禁止多開", L"錯誤", MB_OKCANCEL);return 0;}std::cout << "Game Start..." << std::endl;system("pause");CloseHandle(hMutex);return 0;
      }
  • 性能

    • 臨界區在同一進程的線程中比互斥體更快。

  • 功能

    • 互斥體可以跨進程同步,但臨界區只能夠在同一個進程下的線程之間進行同步。

  • 所有權

    • 互斥體有嚴格的所有權要求,只有擁有互斥體權限的線程才能夠釋放它。

  • 死鎖
    • 當線程在持有鎖的情況下意外死亡(異常)
    • 如果線程在持有臨界區鎖的情況下意外終結,這個鎖不會被釋放,導致其他等待該臨界區的線程無法正常執行,造成死鎖。
    • #include <iostream>
      #include <Windows.h>CRITICAL_SECTION CriticalSection = { 0 };DWORD WINAPI WorkThread(LPVOID lp)
      {EnterCriticalSection(&CriticalSection);printf("TID -> %d \r\n", GetCurrentThreadId());Sleep(5000);LeaveCriticalSection(&CriticalSection);return 0;
      }int main()
      {InitializeCriticalSection(&CriticalSection);HANDLE hThread1 = CreateThread(NULL, 0, WorkThread, NULL, 0, NULL);Sleep(1000);TerminateThread(hThread1, 1);HANDLE hThread2 = CreateThread(NULL, 0, WorkThread, NULL, 0, NULL);WaitForSingleObject(hThread2, INFINITE);DeleteCriticalSection(&CriticalSection);return 0;
      }
    • 如果線程在持有互斥體鎖的情況下意外終結,Windows會自動釋放其所有權,使得其他線程可以繼續正常執行。
    • #include <iostream>
      #include <Windows.h>HANDLE hMutex = NULL;DWORD WINAPI WorkThread1(LPVOID lp)
      {WaitForSingleObject(hMutex, INFINITE);printf("TID -> %d \r\n", GetCurrentThreadId());Sleep(5000);TerminateThread(GetCurrentThread(), -1);//todoreturn 0;
      }DWORD WINAPI WorkThread2(LPVOID lp)
      {printf("Wait For Thread1 Leave\r\n");WaitForSingleObject(hMutex, INFINITE);printf("TID -> %d \r\n", GetCurrentThreadId());ReleaseMutex(hMutex);return 0;
      }int main()
      {hMutex = CreateMutex(NULL, FALSE, NULL);HANDLE hThread1 = CreateThread(NULL, 0, WorkThread1, NULL, 0, NULL);Sleep(1000);HANDLE hThread2 = CreateThread(NULL, 0, WorkThread2, NULL, 0, NULL);WaitForSingleObject(hThread2, INFINITE);CloseHandle(hMutex);CloseHandle(hThread1);CloseHandle(hThread2);return 0;
      }

Semaphore

  • 信號量是一種同步對象,用于控制多個線程對共享資源的訪問。它是一個計數器,用來表示可用資源的數量。當信號量的值大于0,它表示有資源可用;當值為0,表示沒有可用資源。

    • 等待:試圖減少信號量的值。如果信號量的值大于0,減1并繼續執行。如果信號量的值為0,則線程阻塞,直到信號量的值變為大于0。

    • 釋放:增加信號量的值。如果有其他線程因等待這個信號量而阻塞,它們中的一個將被喚醒。

  • 創建信號量

    • 在 Windows 系統中,使用 CreateSemaphoreCreateSemaphoreEx 函數創建信號量。

  • 等待(Wait)和釋放(Release)信號量

    • 等待信號量通常使用 WaitForSingleObjectWaitForMultipleObjects 函數。

    • 釋放信號量使用 ReleaseSemaphore 函數。

#include <iostream>
#include <Windows.h>#define MAX_COUNT_SEMAPHORE 3HANDLE g_SemapHore = NULL;
HANDLE g_hThreadArr[10] = { 0 };DWORD WINAPI WorkThread(LPVOID lp)
{WaitForSingleObject(g_SemapHore, INFINITE);for (size_t i = 0; i < 10; i++){std::cout << "COUNT -> " << (int)lp << std::endl;Sleep(500);}ReleaseSemaphore(g_SemapHore, 1, NULL);return 0;
}int main()
{g_SemapHore = CreateSemaphore(NULL,						//安全屬性MAX_COUNT_SEMAPHORE,		//初始計數MAX_COUNT_SEMAPHORE,		//最大計數NULL						//信號名稱);if (g_SemapHore == NULL){std::cout << GetLastError() << std::endl;return 1;}for (size_t i = 0; i < 10; i++){g_hThreadArr[i] = CreateThread(NULL,0,WorkThread,(LPVOID)i,0,NULL);}WaitForMultipleObjects(10, g_hThreadArr, TRUE, INFINITE);//closehandlereturn 0;
}

Event

  • 在Windows編程中,事件是一種同步機制,用于在多個線程之間發送信號。事件對象可以是手動重置自動重置

    • 手動重置事件(Manual Reset Event):當事件被設置(signaled)后,它將保持這個狀態直到顯式地被重置。這意味著多個等待該事件的線程都可以在事件被重置之前被喚醒。

    • 自動重置事件(Auto Reset Event):當事件被一個等待的線程接收(signaled)后,系統會自動將事件狀態重置為非信號狀態(non-signaled)。這意味著每次只允許一個線程被喚醒。

  • 創建事件

    • 使用Windows API函數CreateEvent可以創建一個事件對象

    • lpEventAttributes:指向安全屬性的指針,如果設置為NULL,則使用默認安全性。

    • bManualReset:如果為TRUE,則創建一個手動重置事件,否則創建自動重置事件。

    • bInitialState:如果為TRUE,則初始狀態為信號狀態;如果為FALSE,則為非信號狀態。

    • lpName:事件的名稱。

  • 設置事件(將事件狀態設置為信號狀態)使用SetEvent函數

  • 重置事件(將事件狀態設置為非信號狀態)使用ResetEvent函數

  • 等待事件 等待一個事件對象變為信號狀態使用WaitForSingleObject函數

#include <iostream>
#include <Windows.h>DWORD WINAPI WorkThread(LPVOID lp)
{HANDLE hEvent = *(HANDLE*)lp;std::cout << "Thread - " << GetCurrentThreadId() << " Waiting For Event" << std::endl;WaitForSingleObject(hEvent, INFINITE);std::cout << "Thread - " << GetCurrentThreadId() << " actived" << std::endl;return 0;
}int main()
{HANDLE hThreads[3] = { 0 };HANDLE hEvent = NULL;hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);if (hEvent == NULL) return 0;for (size_t i = 0; i < 3; i++){hThreads[i] = CreateThread(NULL, 0, WorkThread, &hEvent, 0, NULL);}Sleep(2000);SetEvent(hEvent);WaitForMultipleObjects(3, hThreads, TRUE, INFINITE);CloseHandle(hEvent);return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/41771.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/41771.shtml
英文地址,請注明出處:http://en.pswp.cn/web/41771.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

探索企業信用巔峰:3A企業認證的魅力與價值

在現代商業環境中&#xff0c;企業的信用和信譽是其發展的核心要素之一。3A企業認證作為信用評級的最高等級&#xff0c;正在吸引越來越多企業的關注。究竟什么是3A企業認證&#xff1f;它為什么對企業如此重要&#xff1f;本文將深入探討3A企業認證的獨特魅力和巨大價值。 3A企…

0Day漏洞防御篇:GeoServer CVE-2024-36401遠程代碼執行漏洞

GeoServer是一個用Java編寫的開源軟件服務器&#xff0c;允許用戶共享和編輯地理空間數據。它為提供交互操作性而設計&#xff0c;使用開放標準發布來自任何主要空間數據源的數據。GeoServer存在遠程代碼執行漏洞&#xff08;CVE-2024-36401&#xff09;&#xff0c;未經身份認…

Spring整合SpringSecurity

SpringSecurity基礎使用 SpringSecurity是一個安全框架&#xff0c;主要功能是認證和授權 從Spring入手SpringSecurity 1. Spring整合SpringSecurity applicationContext.xml <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http…

大模型幻覺問題知識點總結

大模型幻覺問題知識點總結 定義&#xff1a; 大模型幻覺問題是指在自然語言處理&#xff08;NLP&#xff09;中&#xff0c;基于大規模預訓練模型&#xff08;如GPT-3、BERT等&#xff09;生成的文本看似合理且連貫&#xff0c;但實際上包含錯誤、不準確或虛假的信息。這種現象…

Aigtek高壓放大器指標有哪些要求和標準

高壓放大器是一類關鍵的電子設備&#xff0c;用于放大電信號并提供強大的輸出。在不同的應用領域&#xff0c;高壓放大器可能有不同的要求和標準。以下是一些常見的高壓放大器指標要求和標準&#xff0c;以確保其性能和可靠性&#xff1a; 1.幅度增益和頻率響應 高壓放大器的主…

人大金倉攜手中國一汽引領國產數據庫行業新浪潮

在國產化政策的推動下,人大金倉攜手中國一汽聯合開發更貼近汽車產業特定需求的數據庫功能和組件。從2023年2月至今,人大金倉已累計部署690套數據庫,適配應用系統170個,支撐中國一汽20多個核心系統和重要系統。目前,中國一汽在國內企業數據庫國產化替換率遙遙領先。此次合作為國…

貓咪健康新選擇!福派斯鮮肉貓糧里的果蔬纖維大揭秘

你們是不是對福派斯鮮肉貓糧中那些豐富的果蔬粗纖維特別好奇呢&#xff1f;&#x1f914; 其實&#xff0c;這些看似簡單的粗纖維&#xff0c;對貓咪的健康可是大有裨益的&#xff01; 粗纖維在貓糧中起到多種重要作用&#xff0c;并且對貓咪的健康和消化系統有著顯著的影響。以…

熱門開源項目推薦:探索開源世界的精彩

熱門開源項目推薦 隨著開源程序的發展&#xff0c;越來越多的程序員開始關注并加入開源大模型的行列。開源不僅為個人學習和成長提供了絕佳的平臺&#xff0c;也為整個技術社區帶來了創新和進步。無論你是初學者還是經驗豐富的開發者&#xff0c;參與開源項目都能讓你受益匪淺…

鄉村振興指數與其30個原始變量數據(Shp/Dta/Excel格式,2000-2022年)

數據簡介&#xff1a;這份數據是我國各地級市鄉村振興指數與其30各原始變量數據并對其進行地圖可視化表達。城鎮化是當今中國社會經濟發展的必由之路。當前我國城鎮化處于發展的關鍵時期&#xff0c;但城鎮化發展的加快卻是一把雙刃劍&#xff0c;為何要如此形容呢?因為當前城…

職升網:一級注冊計量師就業方向如何?

首先我們要知道&#xff0c;一級注冊計量師可以聘為工程師&#xff0c;可以負責計量基準和標準的量值傳遞工作。它可以從事一下7個方面的工作&#xff1a; 1.負責制定計量管理制度、工作計劃、并組織實施&#xff1b; 2.建設期參與設計工程等計量方面的工作&#xff0c;編制計…

k8s-第十二節-DaemonSet

DaemonSet是什么? DaemonSet 是一個確保全部或者某些節點上必須運行一個 Pod的工作負載資源(守護進程),當有node(節點)加入集群時, 也會為他們新增一個 Pod。 下面是常用的使用案例: 可以用來部署以下進程的pod 集群守護進程,如Kured、node-problem-detector日志收集…

紅黑樹模擬實現

目錄 概念 性質 節點定義 紅黑樹的插入 完整代碼 概念 紅黑樹&#xff0c;是一種二叉搜索樹&#xff0c;但在每個結點上增加一個存儲位表示結點的顏色&#xff0c;可以是Red或Black。通過對任何一條從根到葉子的路徑上各個結點著色方式的限制&#xff0c;紅黑樹確保沒有一條…

充電樁開源平臺,開發流程有圖有工具

慧哥充電樁開源平臺產品研發流程是確保產品從概念階段到市場推廣階段的有序進行的關鍵。以下是對您給出的步驟的詳細解釋和建議&#xff1a; 設計業務流程: 在這一步&#xff0c;團隊需要確定產品的核心功能、目標用戶以及如何滿足用戶需求。進行市場調研&#xff0c;了解競爭…

PostMan Error:Maximum response size reached

一、問題描述 用postman本地測試&#xff0c;restful api接口導出文件&#xff0c;文件大小為190M&#xff0c;服務沒問題&#xff0c;總是在導出時&#xff0c;拋出&#xff1a;Error:Maximum response size reached。開始以為是服務相應文件過大或者相應時間超時導致的。其實…

ts和js的關系

https://www.typescriptlang.org/zh/docs/handbook/typescript-from-scratch.html TypeScript&#xff08;TS&#xff09;和 JavaScript&#xff08;JS&#xff09;都是用于開發前端和后端應用的編程語言&#xff0c;但它們有一些顯著的區別。以下是主要的區別&#xff1a; 1…

雙向鏈表 -- 詳細理解和實現

歡迎光顧我的homepage 前言 雙向鏈表是一種帶頭雙向循環的鏈表。在雙向鏈表中&#xff0c;首先存在著一個頭結點&#xff1b;其次每個節點有指向下一個節點的指針next 和指向上一個節點的指針prev &#xff1b…

Trimble realworks 2024.02 中文激活版獲取License下載軟件

Trimble realworks 2024 是領先的3D點云和2D圖像處理解決方案&#xff0c;使用可您提供了一組用于處理的工具&#xff0c;以便為您的應用程序&#xff08;或項目&#xff09;獲取必要的信息。此處理可以分為三種模式&#xff0c;在注冊中&#xff0c;您可以注冊相對于其他掃描和…

通信協議_Modbus協議簡介

概念介紹 Modbus協議&#xff1a;一種串行通信協議&#xff0c;是Modicon公司&#xff08;現在的施耐德電氣Schneider Electric&#xff09;于1979年為使用可編程邏輯控制器&#xff08;PLC&#xff09;通信而發表。Modbus已經成為工業領域通信協議的業界標準&#xff08;De f…

大舍傳媒:如何在海外新聞媒體發稿報道摩洛哥?

引言 作為媒體行業的專家&#xff0c;我將分享一些關于在海外新聞媒體發稿報道摩洛哥的干貨教程。本教程將帶您深入了解三個重要的新聞媒體平臺&#xff1a;Mediterranean News、Morocco News和North African News。 地中海Mediterranean News Mediterranean News是一個知名…

合合信息大模型“加速器”重磅上線

大模型技術的發展和應用&#xff0c;預示著更加智能化、個性化未來的到來。如果將大模型比喻為正在疾馳的科技列車&#xff0c;語料便是珍貴的“燃料”。本次世界人工智能大會期間&#xff0c;合合信息為大模型打造的“加速器”解決方案備受關注。 在大模型訓練的上游階段&…