Linux:線程同步與互斥

目錄

線程互斥

初始化?

銷毀

加鎖

解鎖?

線程同步

條件變量

初始化

銷毀

等待條件滿足

喚醒等待

pthread_cond_signal

pthread_cond_broadcast

生產者消費者模型

3種關系

2種角色

1個交易場所?

POSIX信號量

初始化

銷毀

等待

發布


線程互斥

互斥相關概念

臨界資源:多線程執行流共享的資源就叫做臨界資源。?

臨界區:每個線程內部,訪問臨界資源的代碼,就叫做臨界區。

互斥:任何時刻,互斥保證有且只有一個執行流進入臨界區,訪問臨界資源,通常對臨界資源起保護作用。

原子性:不會被任何調度機制打斷的操作,該操作只有兩態,要么完成,要么未完成。


多線程并發操作一些共享變量會有一些問題

例如變量++,--的操作就不能多線程并發訪問

++,--的操作在匯編中需要分為3步

1.將變量從內存加載到寄存器中

2.更新寄存器里面的值,執行+1(-1)操作

3.將新值從寄存器寫回會變量的內存地址中

因為寄存器用的都是同一個,在并發訪問時就會出現問題

要解決以上問題,需要做到三點:

1.代碼必須要有互斥行為:當代碼進入臨界區執行時,不允許其他線程進入該臨界區。?

2.如果多個線程同時要求執行臨界區的代碼,并且臨界區沒有線程在執行,那么只能允許一個線程進入該臨界區。

3.如果線程不在臨界區中執行,那么該線程不能阻止其他線程進入臨界區。

想要做到這三點,我們可以使用一把鎖。Linux上提供的這把鎖叫互斥量?

pthread_mutex_t?

這是一個互斥鎖的類型,定義在POSIX線程庫中。

互斥鎖用于保護共享資源的訪問,確保在多線程環境中,同一時間只有一個線程可以訪問該資源,從而避免數據競爭和不一致的問題。

我們可以用這個類型來定義一個鎖變量,并初始化它

初始化?

方法1:

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER?

PTHREAD_MUTEX_INITIALIZER這是一個宏,用于初始化靜態分配的互斥鎖

方法2:

#include <pthread.h>int pthread_mutex_init(pthread_mutex_t *mutex, 
const pthread_mutexattr_t *mutexattr);

mutex:指向要初始化的互斥鎖對象的指針

mutexattr:指向互斥鎖屬性對象的指針。如果為NULL,則使用默認屬性(一般情況使用NULL即可)

返回值:

成功:返回0?

失敗:返回錯誤碼

銷毀

鎖也需要像malloc,new出來的動態內存一樣需要我們手動釋放,但并不是所有情況都需要手動釋放的

當使用PTHREAD_MUTEX_INITIALIZER初始化的互斥量不需要銷毀

#include <pthread.h>int pthread_mutex_destroy(pthread_mutex_t *mutex);

mutex:指向要銷毀的互斥鎖對象的指針

返回值:

成功:返回0?

失敗:返回錯誤碼

加鎖

我們可以對一段代碼區進行加鎖,這樣就只能有單執行流訪問一段代碼了

#include <pthread.h>int pthread_mutex_lock(pthread_mutex_t *mutex);

pthread_mutex_lock用于鎖定一個互斥鎖

mutex:指向要鎖定的互斥鎖對象的指針

返回值:

成功:返回0?

失敗:返回錯誤碼

解鎖?

有加鎖當然也會有解鎖,加鎖和解鎖之間的區域就是我們擁有鎖的區域

#include <pthread.h>int pthread_mutex_unlock(pthread_mutex_t *mutex);

pthread_mutex_unlock用于解鎖一個互斥鎖

mutex:指向要解鎖的互斥鎖對象的指針

返回值:

成功:返回0?

失敗:返回錯誤碼

線程同步

條件變量

條件變量是一種在多線程編程中用于線程同步的機制,它允許線程在某些條件不滿足時進入等待狀態,直到條件滿足時才被喚醒繼續執行。?

初始化

初始化一個條件變量。

int pthread_cond_init(pthread_cond_t *cond
, const pthread_condattr_t *cond_attr);

cond:指向條件變量的指針,需要初始化的條件變量。

cond_attr:?指向條件變量屬性的指針。如果為NULL,則使用默認屬性。

返回值:

成功:返回0?

失敗:返回錯誤碼

銷毀

銷毀一個條件變量,釋放相關資源。?

int pthread_cond_destroy(pthread_cond_t *cond);

?cond:指向條件變量的指針,需要銷毀的條件變量。

返回值:

成功:返回0?

失敗:返回錯誤碼

等待條件滿足

使線程進入等待狀態,直到條件變量被通知。?

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);

cond:指向條件變量的指針。

mutex:指向互斥鎖的指針,該互斥鎖必須已經被當前線程鎖定。

當調用pthread_cond_wait的時候,線程會釋放mutex,并進入等待狀態

當條件變量被通知時,線程會被喚醒,并重新嘗試獲取mutex

喚醒等待

pthread_cond_signal

通知一個等待條件變量的線程。

int pthread_cond_signal(pthread_cond_t *cond);

cond:指向條件變量的指針。

返回值:

成功:返回0?

失敗:返回錯誤碼

pthread_cond_broadcast

通知所有等待條件變量的線程。

int pthread_cond_broadcast(pthread_cond_t *cond);

cond:指向條件變量的指針。

返回值:

成功:返回0?

失敗:返回錯誤碼

生產者消費者模型

3種關系

生產者之間:競爭關系,互斥關系

消費者之間:競爭關系,互斥關系

生產者和消費者之間:競爭關系,互斥關系,同步關系

2種角色

生產者角色和消費者角色

1個交易場所?

以特定結構構成的內存空間

POSIX信號量

初始化

初始化一個信號量。

#include <semaphore.h>int sem_init(sem_t *sem, int pshared, unsigned int value);

sem:指向信號量的指針。

pshared:指定信號量是否可以在不同進程之間共享。為0:信號量僅在當前進程內的線程之間共享。非0:信號量可以在不同進程之間共享(需要映射到共享內存)

value:信號量的初始值。

返回值:

成功:返回0?

失敗:返回錯誤碼

銷毀

銷毀一個信號量,釋放相關資源。?

#include <semaphore.h>int sem_destroy(sem_t *sem);

sem:指向信號量的指針。

返回值:

成功:返回0?

失敗:返回錯誤碼

等待

使線程進入等待狀態,直到信號量的值大于零,然后將信號量的值減一。

#include <semaphore.h>int sem_wait(sem_t *sem);

sem:指向信號量的指針。

返回值:

成功:返回0?

失敗:返回錯誤碼

發布

將信號量的值加一,通知等待信號量的線程。

#include <semaphore.h>int sem_post(sem_t *sem);

sem:指向信號量的指針。

返回值:

成功:返回0?

失敗:返回錯誤碼


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

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

相關文章

LeetCode --- 448 周賽

題目列表 3536. 兩個數字的最大乘積 3537. 填充特殊網格 3538. 合并得到最小旅行時間 3539. 魔法序列的數組乘積之和 一、兩個數字的最大乘積 由于數據都是正數&#xff0c;所以乘積最大的兩個數&#xff0c;本質就是找數組中最大的兩個數即可&#xff0c;可以排序后直接找到…

Azure Document Intelligence

Azure Document Intelligence(以前稱為 Form Recognizer)是一項云服務&#xff0c;可用于從文檔中提取文本、鍵值對、表等信息。下面是一個使用 Python SDK 進行文檔轉換和提取信息的基本示例。 1. 安裝依賴 首先&#xff0c;你需要安裝 azure-ai-formrecognizer 庫&#xff0c…

51單片機快速成長路徑

作為在嵌入式領域深耕18年的工程師&#xff0c;分享一條經過工業驗證的51單片機快速成長路徑&#xff0c;全程干貨無注水&#xff1a; 一、突破認知誤區&#xff08;新手必看&#xff09; 不要糾結于「匯編還是C」&#xff1a;現代開發90%場景用C&#xff0c;掌握指針和內存管…

SQLite數據庫加密(Java語言、python語言)

1. 背景與需求 SQLite 是一種輕量級的關系型數據庫,廣泛應用于嵌入式設備、移動應用、桌面應用等場景。為了保護數據的隱私與安全,SQLite 提供了加密功能(通過 SQLCipher 擴展)。在 Java 中,可以使用 sqlite-jdbc 驅動與 SQLCipher 集成來實現 SQLite 數據庫的加密。 本…

《AI大模型應知應會100篇》第53篇:Hugging Face生態系統入門

第53篇&#xff1a;Hugging Face生態系統入門 ——從模型獲取到部署的全流程實戰指南 &#x1f4cc; 摘要 在人工智能快速發展的今天&#xff0c;Hugging Face已成為自然語言處理&#xff08;NLP&#xff09;領域最具影響力的開源平臺之一。它不僅提供豐富的預訓練模型、強大…

什么是向量數據庫?向量數據庫和關系數據庫有什么區別?

什么是向量數據庫&#xff1f; 向量數據庫是一種專門設計用來存儲、索引和查詢向量數據的數據庫系統。在當今的人工智能和機器學習領域中&#xff0c;向量數據庫變得越來越重要&#xff0c;尤其是在處理高維數據如圖像、音頻和文本等非結構化數據時。 主要用途 相似度搜索&…

關于甲骨文(oracle cloud)丟失MFA的解決方案

前兩年&#xff0c;申請了一個招商的多幣種信用卡&#xff0c;然后就從網上擼了一個oracle的免費1h1g的服務器。 用了一段時間&#xff0c;人家要啟用MFA驗證。 啥叫MFA驗證&#xff0c;類似與短信驗證吧&#xff0c;就是綁定一個手機&#xff0c;然后下載一個app&#xff0c;每…

基于Arduino Nano的DIY示波器

基于Arduino Nano的DIY示波器&#xff1a;打造屬于你的口袋實驗室 前言 在電子愛好者的世界里&#xff0c;示波器是不可或缺的工具之一。它能夠幫助我們觀察和分析各種電子信號的波形&#xff0c;從而更好地理解和調試電路。然而&#xff0c;市面上的示波器價格往往較高&…

LeetCode 解題思路 47(最長回文子串、最長公共子序列)

解題思路&#xff1a; dp 數組的含義&#xff1a; dp[i][j] 是否為回文子串。遞推公式&#xff1a; dp[i][j] s.charAt(i) s.charAt(j) && dp[i 1][j - 1]。dp 數組初始化&#xff1a; 單字符 dp[i][i] true&#xff0c;雙字符 dp[i][i 1] s.charAt(i) s.charA…

通過管道實現C++ Linux獨立進程之間的通信和字符串傳遞

在Linux環境下&#xff0c;獨立進程之間的通信&#xff08;IPC&#xff09;可以通過多種方式實現&#xff0c;包括管道、消息隊列、共享內存和套接字。本文將詳細介紹如何使用管道&#xff08;pipe&#xff09;在C中實現獨立進程之間的通信&#xff0c;并傳遞字符串。 一、管道…

神經網絡極簡入門技術分享

1. 引言 神經網絡是深度學習的基礎&#xff0c;其設計靈感來源于人腦神經元的結構和工作方式。盡管現代神經網絡已經變得異常復雜&#xff0c;但其核心原理卻相對簡單易懂。本報告旨在通過剖析神經網絡的最基本單元——神經元&#xff0c;幫助初學者理解神經網絡的工作原理。 …

五、Hadoop集群部署:從零搭建三節點Hadoop環境(保姆級教程)

作者&#xff1a;IvanCodes 日期&#xff1a;2025年5月7日 專欄&#xff1a;Hadoop教程 前言&#xff1a; 想玩轉大數據&#xff0c;Hadoop集群是繞不開的一道坎。很多小伙伴一看到集群部署就頭大&#xff0c;各種配置、各種坑。別慌&#xff01;這篇教程就是你的“救生圈”。 …

科研項目管理:4款高效工具推薦與效率提升實踐

一般來說&#xff0c;科研項目往往涉及復雜的任務、跨部門協作以及嚴格的時間和預算限制。傳統的管理方式&#xff0c;如電子表格或郵件溝通&#xff0c;難以應對多任務并行、資源分配復雜的需求。借助現代項目管理工具&#xff0c;研究人員能夠優化工作流程、提升團隊協作效率…

如何統一修改word中所有英文字母的字體格式

1.需求分析 我想讓整篇論文中的所有英文字母格式都修改為Time New Roman格式。 2.直觀操作流程 點擊左上角開始 --> 點擊替換 --> 點擊更多 --> 點擊特殊格式 --> 選擇查找內容為任意字母(Y) --> 將光標點到替換內容 --> 點擊格式 --> 點擊字體 --> …

【疑難雜癥2025-003】Java-mvn項目在gitlab-ci構建鏡像時遇到的問題和解決方案

本文由Markdown語法編輯器編輯完成&#xff0e; 1.背景: 之前從同事手里接手了一個java的項目&#xff0c;是用maven構建項目的&#xff0e;由于我們的服務都是基于docker來部署的&#xff0c;因此這個java項目也是要編譯成docker image然后發布&#xff0e;但是之前一直都是…

【RT-Thread Studio】nor flash配置Fal分區

前置條件&#xff1a;【RT-Thread Studio】W25Q128配置 添加 FAL軟件包 配置SFUD驅動程序&#xff0c;使用FAL的設備為W25Q128 將fal_cfg.h和fal_flash_sfud_port.c提取出來&#xff0c;放到自己創建的fal_porting目錄。 修改 fal_flash_sfud_port.c struct fal_flash_dev n…

Spring MVC 視圖解析器 (ViewResolver) 如何配置? Spring Boot 是如何自動配置常見視圖解析器的?

我們來詳細分析一下視圖解析器 (ViewResolver) 的配置以及 Spring Boot 是如何自動配置它們的。 視圖解析器 (ViewResolver) 是什么&#xff1f; 在 Spring MVC 中&#xff0c;當控制器 (Controller) 方法處理完請求并返回一個邏輯視圖名 (String) 時&#xff0c;DispatcherS…

理解網站導航文件:robots.txt、sitemap.xml與LLMs.txt的全面解析

在當今數字化時代&#xff0c;網站不僅需要為人類用戶提供良好的瀏覽體驗&#xff0c;還需要考慮搜索引擎和人工智能系統的可訪問性。本文將深入探討三種關鍵的網站導航文件&#xff1a;傳統的robots.txt和sitemap.xml&#xff0c;以及新興的LLMs.txt&#xff0c;分析它們的功能…

leetcode 349. Intersection of Two Arrays

題目描述 題目限制0 < nums1[i], nums2[i] < 1000&#xff0c;所以可以開辟一個1001個元素的數組來做哈希表。 class Solution { public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {vector<int> table(1001,0…

【軟件工程】軟件多缺陷定位方法總結

軟件多缺陷定位(Multi-Fault Localization)是軟件工程中的一個重要研究方向,旨在同時定位代碼中存在的多個缺陷(Bug)。由于多個缺陷可能相互干擾(如掩蓋錯誤行為),導致傳統單缺陷定位方法效果下降,因此需要針對多缺陷場景的特殊性設計方法。以下是常見的多缺陷定位方法…