C# 線程同步(一)同步概念介紹

目錄

1.阻塞(Blocking)

2.阻塞 VS 輪詢

3.線程狀態


????????到目前為止,我們已經闡述了如何在線程上啟動任務、配置線程以及實現雙向數據傳遞。同時,我們也說明了局部變量是線程私有的,而引用可以通過共享字段在線程間傳遞以實現通信。

下一步的關鍵是同步機制:通過協調線程行為來獲得可預測的結果。當多個線程訪問同一數據時,同步顯得尤為重要——這個領域看似簡單卻暗藏風險。

同步構造可分為四大類別:

  1. 簡單阻塞方法
    這類方法通過等待其他線程結束或計時完成來實現同步。例如:SleepJoin?和?Task.Wait?都屬于簡單阻塞方法。

  2. 鎖定構造
    用于限制同時執行某段代碼或操作的線程數量。最常見的獨占鎖(如?lock/Monitor.Enter/Monitor.ExitMutex?和?SpinLock)僅允許一個線程進入,確保競爭線程訪問共享數據時互不干擾。非獨占鎖包括信號量(Semaphore/SemaphoreSlim)和讀寫鎖。

  3. 信號構造
    允許線程暫停運行直至接收到其他線程的通知,從而避免低效的輪詢。常用信號機制有兩種:事件等待句柄(event wait handles)和?Monitor?的?Wait/Pulse?方法。.NET Framework 4.0 新增了?CountdownEvent?和?Barrier?類。

  4. 非阻塞同步構造
    通過調用處理器原語來保護共享字段的訪問。CLR 和 C# 提供的非阻塞構造包括:Thread.MemoryBarrierThread.VolatileReadThread.VolatileWritevolatile?關鍵字以及?Interlocked?類。

除最后一類外,阻塞機制在其他類別中均占核心地位。下面我們將簡要探討這一概念。

1.阻塞(Blocking)

????????當線程因某些原因暫停執行時(例如通過?Sleep?進入休眠,或通過?Join/EndInvoke?等待其他線程結束),該線程即被視為阻塞狀態。阻塞線程會立即釋放其處理器時間片,此后在阻塞條件滿足前不再消耗任何處理器資源。可通過線程的?ThreadState?屬性檢測阻塞狀態:

bool blocked = (someThread.ThreadState & ThreadState.WaitSleepJoin) != 0;
(由于線程狀態可能在檢測與后續操作之間發生變化,此代碼僅適用于診斷場景。)

當線程阻塞或解除阻塞時,操作系統會執行上下文切換。這將產生幾微秒的開銷。

線程會通過以下四種方式解除阻塞(當然,按電腦電源鍵不算!):

  1. 阻塞條件得到滿足

  2. 操作超時(如果指定了超時時間)

  3. 通過Thread.Interrupt被中斷

  4. 通過Thread.Abort被中止

需要注意的是,如果線程是通過(已棄用的)Suspend方法暫停執行的,則不會被判定為處于阻塞狀態。

2.阻塞 VS 輪詢

當線程需要暫停直到特定條件滿足時,通常有兩種實現方式:

  1. 阻塞等待(高效方式)
    通過信號和鎖機制實現,線程會進入阻塞狀態直到條件滿足,此時操作系統會調度其他線程執行。

  2. 輪詢等待(簡單但低效)
    線程通過循環檢測條件來實現等待,例如:

while (!proceed);  // 忙等待

while (DateTime.Now < nextStartTime); // 時間等待

性能考量:

  • 純輪詢會完全占用CPU資源,因為CLR和操作系統會認為線程正在進行重要計算

  • 這種方式的CPU利用率是100%,極其浪費系統資源

改進方案:
可以采用混合阻塞的方式:

while (!proceed) Thread.Sleep(10);  // 每次檢查后休眠10ms

雖然不夠優雅,但相比純輪詢能顯著降低CPU占用率。不過需要注意共享變量(如proceed標志)的并發訪問問題,正確的鎖和信號量使用可以避免這些問題。

適用場景:
當預期條件能在極短時間內(如幾微秒)滿足時,短暫輪詢可能更高效,因為它避免了上下文切換的開銷和延遲。.NET框架為此提供了專門的工具類和方法,這些內容將在并行編程章節詳細介紹。

這里小節一下:

  • 阻塞等待:適合大多數情況,資源利用率高

  • 純輪詢:簡單但資源浪費嚴重

  • 混合模式:折中方案,需要處理并發問題

  • 微秒級等待:特殊場景下短暫輪詢可能更優

3.線程狀態

????????您可以通過ThreadState屬性查詢線程的執行狀態。該屬性返回一個ThreadState類型的標志枚舉,它以位運算方式組合了三個"層次"的數據。不過,大多數枚舉值都是冗余的、未使用的或已廢棄的。下圖展示了其中一個"層次":

以下代碼可將ThreadState精簡為四個最常用的狀態值:未啟動(Unstarted)、運行中(Running)、等待休眠或加入(WaitSleepJoin)和已停止(Stopped):

public static ThreadState SimpleThreadState(ThreadState ts)
{return ts & (ThreadState.Unstarted |ThreadState.Running |ThreadState.WaitSleepJoin |ThreadState.Stopped);
}

ThreadState屬性適用于診斷目的,但不適合用于同步控制,因為在檢測線程狀態和基于該狀態執行操作之間,線程狀態可能會發生變化。


本節完,下一節將開始介紹同步工具

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

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

相關文章

解決leetcode第3588題.找到最大三角形面積

3588.找到最大三角形面積難度&#xff1a;中等問題描述&#xff1a;給你一個二維數組coords&#xff0c;大小為nx2&#xff0c;表示一個無限笛卡爾平面上n個點的坐標。找出一個最大三角形的兩倍面積&#xff0c;其中三角形的三個頂點來自coords中的任意三個點&#xff0c;并且該…

WIFI 安全測試記錄

之前為實訓課特意買的無線網卡沒用上&#xff0c;但是我怎么可能讓他荒廢。所以用了幾個下午&#xff0c;淺學了WiFi&#xff0c;當然沒找到什么好教材&#xff0c;自己摸索著學的很基礎&#xff0c;主要是當練習了&#xff0c;特此把我此前學習…WiFi密碼實踐過程寫上來。 省流…

android14設置--網絡--Internet副標題修改

收銀機訂制項目 插SIM卡&#xff0c;設備使用數據流量時&#xff0c;設置–網絡–Internet副標題顯示對應SIM卡運營商名稱&#xff0c;客戶要求修改這時的名稱(注意圖標也要同步修改) packages\apps\Settings\src\com\android\settings\network\InternetPreferenceController.j…

Web3區塊鏈有哪些崗位?

Web3區塊鏈領域的崗位豐富多樣&#xff0c;涵蓋技術開發、產品管理、運營、商務等多個方面&#xff0c;以下是具體介紹&#xff1a; - 技術開發類&#xff1a; - 智能合約開發工程師&#xff1a;負責編寫、審計和優化智能合約&#xff0c;常見于DeFi開發&#xff0c;包括抵押…

解決 Spring Boot 對 Elasticsearch 字段沒有小駝峰映射的問題

場景重現在使用 MyBatis/Mybatis-Plus 框架對 MySQL 操作時習慣了字段名小駝峰映射&#xff0c;然而在操作 Elasticsearch 時發現字段名沒有小駝峰映射。解決方法1. 使用 ObjectMapper 手動轉換&#xff1a; 這是最直接也最常用的方法。 在 Spring Boot 應用中使用 ObjectMappe…

Error:Cannot find module ‘chokidar‘

錯誤復現 在vue開發中&#xff0c;出現報錯&#xff1a;Error&#xff1a;Cannot find module ‘chokidar’ 原因 缺包導致 解決方案 直接安裝依賴包 npm install chokidar依舊無效&#xff0c;刪除node_modules重新安裝 rm -rf node_modules npm i

Spring AI 向量數據庫詳解與 RAG 簡單實戰項目

一、什么是向量數據庫&#xff1f; 向量數據庫用于存儲、檢索稠密語義向量&#xff08;Embedding&#xff09;&#xff0c;是構建 RAG&#xff08;檢索增強生成&#xff09;系統的核心組件。它支持近似最近鄰搜索&#xff08;ANN&#xff09;&#xff0c;可根據語義相似度找出…

【RK3568+PG2L50H開發板實驗例程】Linux部分/FPGA FSPI 通信案例

本原創文章由深圳市小眼睛科技有限公司創作&#xff0c;版權歸本公司所有&#xff0c;如需轉載&#xff0c;需授權并注明出處&#xff08;www.meyesemi.com) 1. 簡介 本案例旨在 ARM端運行 Linux系統&#xff0c;基通過 FSPI測試。 2. ARM端和 FPGA端通信流程 (1)ARM端實現SP…

github如何創建一個自己的倉庫保姆級教程

文章目錄 準備階段(github官網)添加ssh公鑰添加token創建倉庫 本地設置本地代理創建倉庫添加文件到倉庫進行提交 準備階段(github官網) 添加ssh公鑰 創建SSH KEY。先看一下你C盤用戶目錄下有沒有.ssh目錄&#xff0c;有的話看下里面有沒有id_rsa和id_rsa.pub這兩個文件&#…

LabVIEW 網絡流通信功能

LabVIEW 的網絡流技術實現主機 VI&#xff08;Host VI&#xff09;與客戶端 VI&#xff08;ClientVI&#xff09;間的雙向數據交互&#xff0c;包含命令發送與波形數據傳輸&#xff0c;支持跨設備、跨進程的實時通信&#xff0c;滿足分布式系統中數據交互與控制需求。 主機 VI邏…

Prompt 精通之路(一)- AI 時代的新語言:到底什么是 Prompt?為什么它如此重要?

AI 時代的新語言&#xff1a;到底什么是 Prompt&#xff1f;為什么它如此重要&#xff1f; 標簽&#xff1a; #Prompt新手指南 #提示詞入門 #AI指令 #人工智能 #ChatGPT &#x1f680; Prompt 精通之路&#xff1a;系列文章導航 第一篇&#xff1a;AI 時代的新語言&#xff1a…

uniapp 滾動tab

uniapp woui unibest <route lang"json5">{style: {navigationBarTitleText: 知識產權,navigationBarBackgroundColor: #C80F06,navigationBarTextStyle: white,backgroundColorTop: #C80F06,},} </route> <template><view class"bgc-b …

日事清駕駛艙模式上線:實時數據更新+項目管理+數據可視化,提升決策效率?

大家好&#xff01;我們在日事清最新更新中推出了一個令人激動的新功能——駕駛艙模式。這一全新界面將為企業管理者和團隊提供一個全面、實時的數據展示平臺。下面&#xff0c;讓我們詳細了解這個功能如何幫助您更好地把握企業動態和提升決策效率。 快速入口&#xff1a;一鍵激…

【Maven】Maven深度避坑指南:依賴沖突全維度解決方案與工業級實戰(超萬字解析)

注&#xff1a;本文基于50大型企業級項目經驗&#xff0c;結合Maven底層源碼機制&#xff0c;系統化解決依賴沖突問題。包含20個實戰場景、10類特殊案例及5大防御體系構建方案。 Maven深度避坑指南&#xff1a;依賴沖突全維度解決方案與工業級實戰&#xff08;超萬字解析&#…

Rust Web 全棧開發(二):構建 HTTP Server

Rust Web 全棧開發&#xff08;二&#xff09;&#xff1a;構建 HTTP Server Rust Web 全棧開發&#xff08;二&#xff09;&#xff1a;構建 HTTP Server創建成員包/庫&#xff1a;httpserver、http解析 HTTP 請求HTTP 請求的構成構建 HttpRequest 構建 HTTP 響應HTTP 響應的構…

小架構step系列01:小架構初衷

1 概述 小公司做業務服務&#xff0c;需要聚焦到實際的業務上&#xff0c;盡快通過業務服務客戶&#xff0c;給客戶創建價值&#xff0c;公司才能生存下去。在技術上采用的Web應用架構具備以下特點&#xff1a; 主要由開源組件組裝而成。這樣既可以節省成本&#xff0c;也可以把…

蘋果AR/VR頭顯路線圖曝光,微美全息推進AI/AR智能眼鏡新品開啟視覺體驗篇章

日前&#xff0c;郭明錤發表了一篇關于蘋果&#xff08;AAPL.US&#xff09;2025-2028頭戴式產品路線圖的文章&#xff0c;里面提到蘋果正在開發涵蓋MR頭顯、AI眼鏡、AR眼鏡、Birdbath眼鏡等共計7款設備。 蘋果的頭顯設備中&#xff0c;大量出貨的產品是類似于Ray-Ban Meta的智…

python pyecharts 數據分析及可視化(2)

一、任務要求 任務二&#xff1a;感冒高發期分析 【任務說明】 感冒是一種常見的急性上呼吸道病毒性感染性疾病&#xff0c;多由鼻病 毒、副流感病毒、呼吸道合胞病毒、埃可病毒、柯薩奇病毒、冠狀病 毒、腺病毒等引起。臨床表現為鼻塞、噴嚏、流涕、發熱、咳嗽、頭 痛等&#…

React自學 基礎一

React基礎 React 是一個由 Facebook&#xff08;現 Meta&#xff09;開發并維護的、開源的 JavaScript 庫&#xff0c;主要用于 構建用戶界面&#xff08;UI&#xff09;&#xff0c;尤其是單頁面應用程序中的動態、交互式界面。 簡單示例&#xff1a; import React, { useSt…

PHP語法基礎篇(八):超全局變量

超全局變量是在 PHP 4.1.0 中引入的&#xff0c;并且是內置變量&#xff0c;可以在所有作用域中始終可用。 PHP 中的許多預定義變量都是"超全局的"&#xff0c;這意味著它們在一個腳本的全部作用域中都可用。在函數或方法中無需執行 global $variable; 就可以訪問它們…