Linux: 線程同步

目錄

一 前言

二 線程饑餓

三 線程同步

四 條件變量

1. cond (?condition)

2. pthread_cond_wait()?:

3. pthread_cond_signal()

?五 條件變量的使用


一 前言

?在上篇文章Linux : 多線程互斥-CSDN博客我們講解了線程互斥的概念,為了防止多個線程同時訪問一份臨界資源而出問題,我們引入了線程互斥,線程互斥其實就是多個線程同時爭搶一份資源,誰搶到了就是誰的,搶不到的只能等待著下一次搶。雖然解決了多個線程同時訪問同一資源所產生的問題,但是我們思考一下這樣子合理嗎?不合理,這會產生另一種問題——線程饑餓


二 線程饑餓

?那么線程饑餓是什么呢?為了便于理解,我們可以極端的考慮問題,假設在多線程情況下,存在著兩類優先級不同的線程,一類線程的優先級非常高,另一類的線程的優先級非常低,他們開始同時爭搶臨界資源,假設高優先級的線程拿到了資源,上了鎖之后,其他的線程只能等。直到該線程使用完臨近資源后解鎖,接著所有線程又開始爭搶資源,而高優先級的線程因為其優先性會再一次爭搶到資源,如循環往復,導那些低優先級的線程總是在等待中,永遠拿不到或者很少次數拿到資源,這樣被稱為饑餓或者餓死。這種爭搶臨界資源的方式雖然是沒有什么錯誤,但是總歸來說是不合理的。


三 線程同步

在線程只使用互斥的方式去訪問臨界資源的時候,就可能會出現某些線程饑餓的情況。那么在操作系統中有沒有一種機制,在某一時刻既可以只讓一個線程去訪問臨界資源,但是又可以讓所有的的線程按照一定的順序訪問資源呢?所有的線程就像排隊一樣一個個輪流訪問資源,當某一線程訪問玩臨界資源的時候,他就去隊尾等待。這樣所有的線程的執行流都可以訪問到資源,從而杜絕了線程饑餓的問題。 ?這樣的機制叫做——同步,即線程同步:在保證臨界資源安全的前提下,讓執行流訪問臨界資源具有一定的順序性。


四 條件變量

?那么同步是怎么實現的呢?同步離不開一個東西——條件變量條件變量是一種可以實現線程同步的機制,通過條件變量,可以實現讓線程有序的訪問臨界資源

條件變量,顧名思義它是一個執行的“條件”,當線程需要訪問臨界資源時,如果臨界資源不滿足一定的條件,那就讓線程進行等待,如果滿足條件,則讓線程繼續恢復執行的機制。它是?一個?pthread_cond_t?結構體類型的變量,并且在 pthread 庫中也提供了一些條件變量相關的接口。


1. cond (?condition)

pthread_cond_t?是定義條件變量的類型。

條件變量的使用是和互斥鎖差不多的。?

  • 條件變量的初始化可以和互斥量相同有兩種,一種是調用接口 pthread_cond_init() 初始化,第一個參數是條件變量的地址,第二個參數是條件變量的屬性(暫時不考慮)。需要注意的是,用該接口初始化的條件變量在不需要使用的時候,需要調用 pthread_cond_destroy() 接口來銷毀掉。

  • 使用宏初始化的條件變量就不用手動調用接口來銷毀了。

2. pthread_cond_wait()?

條件變量等待的接口

  • 這么多等待的接口中 pthread_cond_wait() 接口是最常用的,它是pthread庫提供的使用條件變量等待的接口,線程調用此接口,線程就會立即進入等待。

  • pthread_cond_timedwait() 也是pthread提供給的使用條件變量等待的接口,不過看他的名字也知道它是一種定時讓線程等待的接口,即可以通過該接口設置一定的時間,在此時間內讓線程等待,如果此時間內,條件滿足了,線程就會被自動喚醒,繼續執行代碼。

  • 我們可以看到這兩個接口的參數中都有 互斥鎖 ,他們是和互斥鎖一起配合使用的。

上面講到了兩個通過條件變量讓線程進行等待的接口,既然有等待的接口,那么自然就存在著通過條件變量去喚醒線程的接口。如下

3. pthread_cond_signal()

調用該接口可以讓某個通過指定條件變量陷入等待的線程被喚醒。


?五 條件變量的使用

下面我們寫個測試使用一下條件變量

#include <iostream>
#include <string>
#include <pthread.h>
#include <unistd.h>int tickets=1000;
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;//定義一個鎖
pthread_cond_t cond =PTHREAD_COND_INITIALIZER;//定義一個條件變量void* start_routine(void* args)
{std::string name =static_cast<const char*>(args);while(true){pthread_mutex_lock(&mutex);pthread_cond_wait(&cond,&mutex);std::cout<<name<<" ->"<<tickets--<<std::endl;pthread_mutex_unlock(&mutex);}
}int main()
{//通過條件變量控制線程的執行pthread_t t1,t2;pthread_create(&t1,nullptr,start_routine,(void*)"thread 1");pthread_create(&t2,nullptr,start_routine,(void*)"thread 2");while(true){sleep(1);pthread_cond_signal(&cond);//喚醒該條件下所以的線程std::cout<<"main thread wake up one thread...."<<std::endl;}pthread_join(t1,nullptr);pthread_join(t2,nullptr);return 0;
}

測試結果?

從測試結果可以看到pthread_cond_signal()對線程的喚醒是以一定順序來進行的。注意,pthread_cond_signal()是一次對一個線程進行喚醒,我們也可以使用? ? ? ? ? ? ? ? ? ? ? pthread_cond_broadcast()來喚醒所有的在等待中的線程。?

int main()
{//通過條件變量控制線程的執行pthread_t t1,t2;pthread_create(&t1,nullptr,start_routine,(void*)"thread 1");pthread_create(&t2,nullptr,start_routine,(void*)"thread 2");while(true){sleep(1);//一次喚醒所以線程pthread_cond_broadcast(&cond);//喚醒該條件下所以的線程std::cout<<"main thread wake up one thread...."<<std::endl;}pthread_join(t1,nullptr);pthread_join(t2,nullptr);return 0;
}

?條件變量:通過條件控制線程的執行

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

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

相關文章

MyBatisPlus-QueryWrapper的exists方法拼接SQL中的EXISTS子句

在 MyBatis-Plus 中,QueryWrapper 的 exists 方法用于拼接 SQL 中的 EXISTS 子句,通常用于構 建子查詢條件。以下是具體用法和示例: ??1. 基本語法?? // 判斷是否存在符合條件的記錄 queryWrapper.exists(String existsSql); queryWrapper.notExists(String existsSq…

[數據結構]哈希表

目錄 1、哈希表 1.1、概念 1.2、沖突 2、哈希函數設計 3、負載因子調節 4、閉散列 5、開散列/哈希桶&#xff08;重點掌握&#xff09; 6、實現哈希桶 6.1、put方法 6.2、HashMap的擴容機制 6.3、get方法 7、HashMap 8、HashSet 8.1、哈希表性能分析 9、hashcod…

VS-Code創建Vue3項目

1 創建工程文件 創建一個做工程項目的文件夾 如&#xff1a;h5vue 2 cmd 進入文件 h5vue 3 輸入如下命令 npm create vuelatest 也可以輸入 npm create vitelatest 4 輸入項目名稱 項目名稱&#xff1a;自已輸入 回車 可以按鍵盤 a (全選) 回車&#xff1a; Playwright…

linux休眠喚醒流程

1、框架 2、休眠流程 應用層通過echo mem > /sys/power/state寫入休眠狀態&#xff0c;給一張大概流程圖 這個操作對應在kernel/power/main.c的state這個attr的store操作 static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr, …

Mysql--基礎知識點--93--兩階段提交

1 兩階段提交 以update語句的具體執行過程為例&#xff1a; 具體更新一條記錄 UPDATE t_user SET name ‘xiaolin’ WHERE id 1;的流程如下&#xff1a; 1.執行器負責具體執行&#xff0c;會調用存儲引擎的接口&#xff0c;通過主鍵索引樹搜索獲取 id 1 這一行記錄&#…

Windows 環境下 Apache 配置 WebSocket 支持

目錄 前言1. 基本知識2. 實戰前言 ?? 找工作,來萬碼優才:?? #小程序://萬碼優才/r6rqmzDaXpYkJZF 爬蟲神器,無代碼爬取,就來:bright.cn 原先寫過apache的http配置:Apache httpd-vhosts.conf 配置詳解(附Demo) 1. 基本知識 ?? WebSocket 是 HTTP 的升級協議 客戶…

UMAEA論文閱讀

Preliminaries MMKG為一個五元組G{E, R, A, V, T}&#xff0c;其中E、R、A和V分別表示實體集、關系集、屬性集和圖像集。 T?ERE是關系三元組集。 給定兩個MMKG G1 {E1, R1, A1, V1, T1} 和 G2 {E2, R2, A2, V2, T2}&#xff0c; MMEA旨在識別每個實體對&#xff08;e1…

AIGC-十款知識付費類智能體完整指令直接用(DeepSeek,豆包,千問,Kimi,GPT)

Unity3D特效百例案例項目實戰源碼Android-Unity實戰問題匯總游戲腳本-輔助自動化Android控件全解手冊再戰Android系列Scratch編程案例軟考全系列Unity3D學習專欄藍橋系列AIGC(GPT、DeepSeek、豆包、千問、Kimi)??關于作者 專注于Android/Unity和各種游戲開發技巧,以及各種資…

Qt界面卡住變慢的解決方法

本質原因: 當Qt界面出現卡頓或無響應時&#xff0c;通常是因為主線程&#xff08;GUI線程&#xff09;被耗時操作阻塞。 完全忘了。。。 Qt Creater解決方法 1. 定位耗時操作 目標&#xff1a;找到阻塞主線程的代碼段。 方法&#xff1a; 使用QElapsedTimer測量代碼執行時間…

【LangChain4j快速入門】5分鐘用Java玩轉GPT-4o-mini,Spring Boot整合實戰!| 附源碼

【LangChain4j快速入門】5分鐘用Java玩轉GPT-4o-mini&#xff0c;Spring Boot整合實戰&#xff01; 前言&#xff1a;當Java遇上大模型 在AI浪潮席卷全球的今天&#xff0c;Java開發者如何快速擁抱大語言模型&#xff1f;LangChain4j作為專為Java打造的AI開發框架&#xff0c…

Vue 3 reactive 和 ref 區別及 失去響應性問題

在 Vue 3 中&#xff0c;reactive 和 ref 是實現響應式數據的兩個核心 API&#xff0c;它們的設計目標和使用場景有所不同。以下是兩者的詳細對比&#xff1a; 1. 基本定義與核心功能 特性reactiveref作用創建對象類型的響應式代理&#xff08;對象、數組、Map 等&#xff09…

第一節:Vben Admin 最新 v5.0初體驗

系列文章目錄 基礎篇 第一節&#xff1a;Vben Admin介紹和初次運行 第二節&#xff1a;Vben Admin 登錄邏輯梳理和對接后端準備 第三節&#xff1a;Vben Admin登錄對接后端login接口 第四節&#xff1a;Vben Admin登錄對接后端getUserInfo接口 第五節&#xff1a;Vben Admin權…

Nginx部署spa單頁面的小bug

沒部署過&#xff0c;都是給后端干的&#xff0c;自己嘗試部署了一個下午終于成功了 我遇到的最大的bug是進入后只有首頁正常顯示 其他頁面全是404&#xff0c;于是問問問才知道&#xff0c;需要這個 location / { try_files $uri $uri/ /index.html; } 讓…

面試算法高頻08-動態規劃-01

動態規劃 遞歸知識要點 遞歸代碼模板&#xff1a;提供遞歸代碼的標準形式public void recur(int level, int param) &#xff0c;包含終止條件&#xff08;if (level> MAX_LEVEL)&#xff09;、當前層邏輯處理&#xff08;process(level, param)&#xff09;、向下一層遞歸…

若依框架前后端分離版部署全流程詳解(本地+服務器+高級配置)

若依框架前后端分離版部署全流程詳解&#xff08;本地服務器高級配置&#xff09; 若依&#xff08;RuoYi&#xff09;作為一款基于SpringBoot和Vue的權限管理系統&#xff0c;憑借其模塊化設計和開箱即用的特性廣受開發者歡迎。本文將從本地部署、服務器部署、高級配置三個維…

醫療設備預測性維護合規架構:從法規遵循到技術實現的深度解析

在醫療行業數字化轉型加速推進的當下&#xff0c;醫療設備預測性維護已成為提升設備可用性、保障醫療安全的核心技術。然而&#xff0c;該技術的有效落地必須建立在嚴格的合規框架之上。醫療設備直接關乎患者生命健康&#xff0c;其維護過程涉及醫療法規、數據安全、質量管控等…

LLMs基礎學習(七)DeepSeek專題(4)

LLMs基礎學習&#xff08;七&#xff09;DeepSeek專題&#xff08;4&#xff09; 文章目錄 LLMs基礎學習&#xff08;七&#xff09;DeepSeek專題&#xff08;4&#xff09;DeepSeek-R1 訓練過程的四個階段具體流程小結 “規則化獎勵”具體原因小結 “自我認知”&#xff08;se…

SQL 速查手冊

前言&#xff1a;SQL&#xff08;Structured Query Language&#xff09;是用于管理關系型數據庫的標準語言&#xff0c;廣泛應用于數據查詢、更新、定義和管理等操作。本文將為你提供一份詳細的 SQL 速查手冊&#xff0c;涵蓋從基礎到高級的各種 SQL 操作&#xff0c;幫助你快…

IDEA 中 Scala 項目遠程連接虛擬機 Spark 環境

IDEA 中 Scala 項目遠程連接虛擬機 Spark 環境 1. 環境準備 確保虛擬機 Spark 環境正常運行 虛擬機中已安裝并啟動 Spark記錄虛擬機的 IP 地址和 Spark 端口&#xff08;默認 7077&#xff09;確保虛擬機防火墻允許相關端口訪問 本地 IDEA 環境配置 安裝 Scala 插件安裝 Spar…

.net core 項目快速接入Coze智能體-開箱即用-全局說明

目錄 一、Coze智能體的核心價值 二、開箱即用-效果如下 三 流程與交互設計 為什么要分析意圖&#xff0c;而不是全部交由AI處理。 四 接入前的準備工作 五&#xff1a;代碼實現----字節Coze 簽署 JWT和獲取Token .net core 項目快速接入Coze智能體-開箱即用 .net core快…