鎖的基本介紹

并發編程的一個最基本問題就是原子性地執行一系列指令。鎖有助于直接解決這一問題。

鎖的基本思想

鎖就是一個變量。這個變量保存了鎖在某一時刻的狀態。它要么是可用的,表示沒有線程持有鎖,要么是被占用的,表示有線程持有鎖,正處于臨界區(訪問共享資源的那部分代碼)。

Pthread鎖

POSIX庫將鎖稱為互斥量(mutex),因為它被用來提供線程之間的互斥。當一個線程在臨界區,它能阻止其它線程進入到本地線程直到本線程離開臨界區。

設計鎖

一個鎖應當能保證不會有第二個線程進入臨界區。另外,還應當保證公平性,所有的線程都有機會公平搶到鎖。在設計鎖時還應該考慮到搶鎖和釋放鎖的開銷。

為了實現上面兩點,我們需要使用硬件和操作系統的支持。

控制中斷

在臨界區關閉中斷。這個方案是為單處理系統開發的。

原子交換(測試并設置)

控制中斷無在多處理器上工作,系統設計者開始讓硬件支持鎖。最簡單的硬件支持就是測試并設置指令(test-and-set instruction),也叫做原子交換。

typedef struct lock_t { int flag; } lock_t;void init(lock_t* mutex)
{mutex->flag = 0;
}void lock(lock_t* mutex)
{while (mutex->flag == 1) //測試; //鎖被其它線程占用,該線程陷入自旋mutex->flag = 1; //設置
}void unlock(lock_t* mutex)
{mutex->flag = 0;
}

這種設置也是有問題的,首先它不能完成讓線程互斥的基本任務。考慮這種情況,當線程1在測試鎖時(只是通過了測試并未設置),發生了中斷切換的線程2,隨后線程2執行了完整的測試和設置,此時再次發生中斷切換到線程1。由于先前線程1已經通過了測試語句,接下來會執行設置代碼。這樣一來,就有兩個線程同時持有鎖了。

在性能上,如果一個線程在等待已經被持有的鎖時,會一直自旋,不停地檢查鎖。這會浪費許多CPU時間。

實現這種鎖,需要一條硬件指令支持。在x86上是xchg指令(原子交換)。下面的代碼片段說明了該指令的工作方式:

int TestAndSet(int* old_ptr, int new)
{int old = *old_ptr;*old_ptr = new;return old;
}

這些代碼都是原子地執行。利用這類原子交換指令可以實現自旋鎖。

typedef struct lock_t
{int flag;
} lock_t;void init(lock_t* lock)
{lock->flag = 0;
}void lock(lock_t* lock)
{while (TestAndSet(lock, 1) == 1);//自旋
}void unlock(lock_t* lock)
{lock->flag = 0;
}

比較并交換

另一個硬件支持是比較并交換指令。

int CompareAndSwap(int *ptr, int expected, int new)
{int actual = *ptr;if (actual == expected)*ptr = new;return actual;
}

鏈接的加載和條件式存儲指令

int LoadLinked(int* ptr)
{return *ptr;
}int StoreConditional(int* ptr, int value)
{if (no one has updated *ptr since the LoadLinked to this address){*ptr = value;return 1;}else{return 0;}
}

獲取并增加

int FetchAndAdd(int *ptr)
{int old = *ptr;*ptr = old + 1;return old;
}typedef struct lock_t
{int ticket;int turn;
} lock_t;void lock_init(lock_t *lock)
{lock->ticket = 0;lock->turn = 0;
}void lock(lock_t* lock)
{int myturn = FetchAndAdd(&lock->ticket);while (lock->turn != myturn); //spin
}void unlock(lock_t* lock)
{FetchAndAdd(&lock->turn);
}

解決自旋時的浪費

在自旋的時候,線程應該放棄CPU,從運行狀態變為就緒狀態。而且我們應該控制釋放鎖時誰可以搶到鎖,這是為了避免性能上的浪費以及餓死的問題。

為此,我們需要操作系統維護一個隊列保存正在等待鎖的線程隊列。這樣我們就可以在鎖被占用時休眠線程,在鎖可用時從隊頭中喚醒一個線程。

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

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

相關文章

【讀代碼】開源流式語音編碼器SecoustiCodec

引言:從LLM到深度語義 在大型語言模型(LLM)驅動的語音交互時代,神經語音編解碼器 (Neural Speech Codec) 扮演著至關重要的角色。它如同 LLM 的“耳朵”和“嘴巴”,負責將連續的語音波形轉換為離散的、可供模型處理的 token,并將模型生成的 token 還原為自然的人聲。 一…

P5967 [POI 2016] Korale 題解

P5967 [POI 2016] Korale 題目描述 有 nnn 個帶標號的珠子,第 iii 個珠子的價值為 aia_iai?。 現在你可以選擇若干個珠子組成項鏈(也可以一個都不選),項鏈的價值為所有珠子的價值和。 給出所有可能的項鏈排序,先按…

SwiftUI 頁面彈窗操作

SwiftUI 頁面彈窗操作指南一、基礎彈窗實現1. Alert 基礎警告框2. ActionSheet 操作菜單3. Sheet 模態視圖4. Popover 浮動視圖二、高級自定義彈窗1. 自定義彈窗組件2. 使用自定義彈窗三、彈窗狀態管理1. 使用環境對象管理彈窗2. 彈窗路由系統四、動畫與過渡效果1. 自定義彈窗動…

OpenCV圖像處理2:邊界填充與平滑濾波實戰

前面學了一些關于opencv圖像處理的內容,現在繼續。一 圖像填充邊界填充(Border Padding)?,即在圖像四周添加指定寬度的像素區域。其核心函數是cv2.copyMakeBorder(),通過不同的填充方式(borderType&#x…

imx6ull-驅動開發篇22——Linux 時間管理和內核定時器

目錄 內核時間管理 系統節拍率 高/低節拍率的優缺點 jiffies 節拍數 時間繞回 時間轉換函數 內核定時器 timer_list 結構體 定時器API函數 init_timer 函數 add_timer 函數 del_timer 函數 del_timer_sync 函數 mod_timer 函數 Linux 內核短延時函數 內核時間管…

路由器數據控制管理層面安全

數據層面:FPM Flexible Packet MatchingFPM是CisCOIOS新一代的ACL根據任意條件,無無狀態的匹配數據包的頭部負載,或者全部分析協議,更易于規則的創建用于替代傳統ACL,對特定惡意流量的基礎架構過濾無狀態ipv4單播不支持…

Vue內置組件全解析:從入門到面試通關

文章目錄Vue內置組件全解析&#xff1a;從入門到面試通關引言&#xff1a;為什么需要內置組件&#xff1f;一、Vue內置組件全景圖二、核心內置組件詳解1. <component> - 動態組件2. <transition> - 過渡動畫3. <keep-alive> - 組件緩存4. <slot> - 內容…

VUE+SPRINGBOOT從0-1打造前后端-前后臺系統-會議記錄

在當今快節奏的工作環境中&#xff0c;會議記錄是每個職場人士都必須要面對的任務。傳統的手動記錄方式不僅效率低下&#xff0c;而且容易遺漏重要信息。隨著Web技術的發展&#xff0c;基于瀏覽器的實時語音轉寫技術為會議記錄提供了全新的解決方案。本文將詳細介紹如何利用Web…

WEB3——水龍頭,如何獲得開發用的測試幣、 Sepolia 測試幣?

注意&#xff1a; 有些水龍頭渠道&#xff0c;要求以太坊幣至少有0.01ETH,設有這個門檻&#xff0c;下面并不是所有渠道都能領取到測試幣&#xff0c;有些可能對領取測試幣有要求&#xff0c;如果想獲得獲取以太坊幣的方法&#xff0c;可以看我其他的文章。 本文整理了多個免費…

C++調試革命:時間旅行調試實戰指南

還在為C的懸垂指針、內存泄漏和并發競態抓狂&#xff1f;讓調試器學會“時光倒流” 凌晨三點&#xff0c;std::thread創建的六個線程中有一個突然吞掉了你的數據&#xff0c;valgrind只告訴你“Invalid read”&#xff0c;而時間旅行調試&#xff08;TTD&#xff09;?? 能讓你…

mysql8.0筆記

1.DDL數據定義語言 DDL是什么——————創建、修改、刪除 數據庫和表結構的命令。 基本語法 針對數據庫的操作 -- 創建數據庫 CREATE DATABASE 數據庫名; -- 比如 CREATE DATABASE myschool; --查看所有數據庫 SHOW DATABASES; --使用某個數據庫 USE myschool; -- 刪除數據庫…

大模型微調【1】之入門

文章目錄說明一 大模型微調技術1.1 微調基礎1.2 量化概念1.3 高效微調方法LoRA&QLoRA1.4 LoRA VS QLoRA1.5 高效微調的應用場景二 主流微調工具2.1 unsloth2.2 LLama-Factory2.3 ms-SWIFT2.4 ColossalAI2.5 底層微調框架推薦2.6 模型性能評估框架EvalScope三 微調所需軟硬件…

深入解析Linux poll()系統調用

&#x1f504; Linux poll() 系統調用詳解一、poll 是干什么的&#xff1f;poll 是 Linux&#xff08;及 POSIX 標準&#xff09;中用于實現 I/O 多路復用&#xff08;I/O Multiplexing&#xff09; 的系統調用&#xff0c;它的核心作用是&#xff1a;讓一個線程能夠同時監視多…

文獻閱讀 | PLoS ONE | SRplot:一個免費的在線平臺,用于數據可視化和圖形

文獻介紹文獻題目&#xff1a; SRplot&#xff1a;一個免費的在線平臺&#xff0c;用于數據可視化和圖形 研究團隊&#xff1a; Yewei Wang&#xff08;中南大學湘雅二醫院&#xff09; 發表時間&#xff1a; 2023-11-09 發表期刊&#xff1a; PLoS ONE 影響因子&#xff1a; 3…

分布式與微服務寶典

分布式理論基礎 1、分布式架構有哪些特點&#xff0c;優勢和缺陷 特點&#xff1a;微服務架構的優點微服務架構的缺陷自由使用不同技術增加故障排除挑戰每一個微服務都側重于單一功能由于遠程調用增加延遲支持單個可部署單元增加了配置與其他操作的工作量允許經常發布軟件難以保…

利用生成式AI與大語言模型(LLM)革新自動化軟件測試 —— 測試工程師必讀深度解析

引言 自動化測試是現代軟件工程的基石&#xff0c;然而&#xff0c;隨著軟件復雜度和迭代速度的飛速提升&#xff0c;傳統自動化測試方法正面臨越來越多的挑戰。 近年來&#xff0c;生成式人工智能&#xff08;Generative AI&#xff09;和大語言模型&#xff08;LLM&#xff0…

JS 與 C++ 雙向通信實戰:基于 WebHostViewListener 的消息處理機制

前言在現代瀏覽器和桌面應用開發中&#xff0c;WebView 嵌入已經成為一種非常常見的 UI 技術方案。無論是基于 Chromium 的 CEF&#xff08;Chromium Embedded Framework&#xff09;、Qt WebEngine&#xff0c;還是自研瀏覽器內核&#xff0c;嵌入 WebView 都能帶來極高的靈活…

模板打印技術——Office XLS 打印模板:為政務土地確權定制的紙張替換利器—仙盟創夢IDE

代碼public static int cyberwin_replaceExcelandoutputPrint(string fisrcpathleurl, DataTable dtInfo, string despath){if (File.Exists(despath) true){//刪除目標文件File.Delete(despath);}File.Copy(fisrcpathleurl, despath);string 目標文件 despath;MSEXCEL.Appli…

可直接運行的 Playwright C# 自動化模板

目錄 目錄結構 1. appsettings.json&#xff08;賬號、URL、路徑配置&#xff09; 2. Program.cs&#xff08;啟動入口&#xff09; 3. SchedulerConfig.cs&#xff08;定時調度&#xff09; 4. SocialSecurityTask.cs&#xff08;自動報社保任務&#xff09; 5. QuerySo…

云平臺監控-云原生環境Prometheus企業級監控實戰

目錄 一、基于 Kubernetes 的 Prometheus 監控方案概述 1. 核心組件及功能 2. 監控流程詳解 3. 關鍵監控指標說明 二、Prometheus 與相關組件部署 1. 克隆項目代碼 2. 安裝 Prometheus Operator 3. 安裝 Prometheus Stack 4. 查看容器運行狀態 三、ServiceMonitor 配…