進程間通信--信號量【Linux操作系統】

文章目錄

  • 并發編程相關基礎概念
  • 信號量
    • 深刻理解信號量
      • 使用共享資源的方式
      • 分塊使用共享資源的方式會出現的問題
      • 舉例子理解信號量的第二個特性---預定
      • 信號量要成為計數器面臨的問題
    • 信號量相關操作接口--POSIX
      • 庫函數:sem_init
      • 庫函數:sem_destroy
      • 庫函數:sem_wait
      • 庫函數:sem_post
    • 信號量相關操作接口--systemV
      • 系統調用:semget
      • 系統調用:semop

并發編程相關基礎概念

在這里插入圖片描述

保護共享內存的本質就是:
對訪問共享內存的代碼(臨界區)進行限制

信號量

信號量和其他進程間通信的作用不太一樣,它主要是用來實現進程(線程)間同步互斥的

信號量(進程)的生命周期也和共享內存一樣:隨內核
所以
①要么由進程使用系統調用釋放信號量
②要么操作系統重啟



深刻理解信號量

信號量本質是一個對資源進行預定的計數器



使用共享資源的方式

訪問臨界資源的時候,有兩種訪問方式:

  • 1.一次直接使用一整個臨界資源
    比如
    我們之前對管道的使用,從來就沒有考慮過寫入位置和讀取位置在哪的問題
    只是直接從管道讀取,直接向管道寫入,是直接以一整個管道為單位進行使用

    • 此時出于對共享資源的保護的互斥性,一次就只能一個進程訪問這個管道
  • 2.把一個臨界資源分成多個分區,讓不同進程可以使用不同分區
    這樣的好處是:

    • 1.可以在不違反保護共享資源特性的情況下,一個共享資源可以被多個進程同時使用(并發使用)
    • 2.申請一塊共享資源非常繁瑣,所以如果多個進程想兩兩通信
      可以只申請一塊共享資源,再把它分區給所有進程使用
    • 只申請一塊共享資源也可以減少使用系統調用


分塊使用共享資源的方式會出現的問題

分塊使用共享資源雖然可以做到一塊共享資源,多個進程并發使用
但是一種方法了解決一個問題,必然又會出現新的問題
這個新的問題就是:
共享資源的分區個數<進程個數怎么辦?

例如
我們把一個共享資源分成了16個區,但是同時來了30個進程要訪問共享資源怎么辦?
在這里插入圖片描述

此時再怎么分配,也不可能讓所有進程同時使用這個共享資源=
只能先分配16個進程,等一些進程使用丸了,再讓剩下的進程進來用
如何做到這一點呢?
使用計數器!!!

  1. 讓計數器等于分區數,這樣一個進程要使用共享資源前,都先判斷一下const是否>0
    如果是就是還有分區空著,可以給它,再count--
    如果不是,就讓進程阻塞等待

  2. 同理,如果有一個進程退出了臨界區,就會有一個分區空出來,count++

所以本質上共享資源使用方法1和2其實是一樣的,因為整體使用時不就是分區個數只有1個嗎?



舉例子理解信號量的第二個特性—預定

我們生活中,不管是看電影還是坐高鐵,都要買票,因為它們的名額都是需要競爭的資源
買票的本質就是:對資源進行預定
就是買到票了,我就算不去,那個資源也是屬于我的

而且票的個數也有限,因為資源的個數有限,不能出現兩個人用同一個資源的情況,所以票又何嘗不是一個計數器呢?

我們上面所說的進程競爭使用共享資源的分區,本質也是如此
只要一個進程搶到了計數器的名額,共享資源中就一定有一個分區會給它

所以信號量的本質是和票一樣,是對資源進行預定的計數器

所以
人們搶高鐵座位,其實是搶票
進程搶共享資源的分區,其實是搶計數器(信號量)名額

所以共享資源分區,最重要的不是分配,而是對計數器(信號量)的正確使用

對共享資源整體使用的時候,計數器count不是等于0就是等于1
此時稱這個計數器為:二元信號量或者鎖



信號量要成為計數器面臨的問題

  • 1.如何讓不同進程看到計數器(信號量)呢?
    讓信號量作為共享資源!!!

  • 2.信號量本身就是共享資源,它去包含其他的共享資源,那誰來保護它呢?
    比如兩個進程同時看見信號量還剩一個,它們同時去搶,同時搶到手,count同時=0
    這不就卡bug了嗎?

信號量本質是一個對共享資源進行預定的計數器
計數器的操作無非就是++和–
只要讓這兩個操作都具有不可中斷的原子性不就可以了嗎?
所以操作系統為信號量專門定義了具有兩個原子性的操作
即P操作[++]和V操作[–]



信號量相關操作接口–POSIX

使用信號量接口之前,需要定義一個信號量對象(sem_t類型)

庫函數:sem_init

  • 頭文件:semaphore.h

  • 參數表:

    • 1.sem_t*sem
      要初始化的信號量的地址

    • 2.int pshared
      1.如果是pshared是0,則表示線程間信號量
      2.如果是pshared非0,則表示進程間信號量

    • 3.unsigned int val
      即:信號量這個計數器的初始值,也就是把共享資源分成幾份/共享資源的個數

  • 作用:
    初始化對應的信號量


庫函數:sem_destroy

  • 頭文件:semaphore.h

  • 參數表:
    sem_t*sem:要銷毀的信號量的地址

  • 作用:
    銷毀對應的信號量


庫函數:sem_wait

  • 頭文件:semaphore.h

  • 參數表:
    sem_t*sem:對應的信號量的地址

  • 作用:
    申請信號量,P操作,信號量–
    (申請信號量失敗【即信號量減到0】,線程/進程會被阻塞)


庫函數:sem_post

  • 頭文件:semaphore.h

  • 參數表:
    sem_t*sem:對應的信號量的地址

  • 作用:
    釋放信號量,V操作,信號量++



信號量相關操作接口–systemV

如果有多個共享內存要分區使用,那么就需要多個信號量

所以操作系統提供信號量,是以信號量集合的方式提供的
即:申請信號量的時候,申請的是一個/多個信號量


系統調用:semget

  • 頭文件:
    sys/types.hsys/ipc.hsys/sem.h

  • 返回值:int類型
    ①成功,返回用戶(進程)使用的信號量集合標識符合條件
    ②失敗,返回-1

  • 參數表:

    • key_t key:內核中唯一標識一個信號量集合(key的獲取和使用方法于共享內存的key一模一樣,使用ftok獲取

    • int nsems:信號量集合中的信號量個數

    • int semflag:位圖標志位
      也和共享內存的一模一樣
      IPC_CREAT:單獨使用的話如果對應的共享內存不存在,就創建。存在就返回shmid
      該選項主要給獲取共享內存的進程使用
      IPC_EXCL:不能單獨使用
      但是
      IPC_CREAT | IPC_EXCL
      如果對應的共享內存不存在,就創建并在頁表建立映射關系
      存在就報錯
      該選項主要給創建共享內存的進程使用

  • 作用:創建(獲取)一個信號量集合


系統調用:semop

  • 頭文件:
    sys/types.hsys/ipc.hsys/sem.h

  • 參數表:

    • int semid:進程使用的信號量集合唯一標識

    • struct sembuf*p:指向一個struct sembuf的數組的起始地址
      struct sembuf
      {
      int sem_num//信號量集合的下標
      short sem_op//-1表示–,1表示++
      short sem_flaf//一般不管,設置為0
      }
      semop這樣設計是為了,可以同時對一個信號量集合中的多個信號量進行PV操作或者對信號量集合進行整體操作

    • ③int nsops :參數②指向的數組的元素個數

  • 作用:對一個信號量集合中的一個/多個信號量進行PV操作

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

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

相關文章

謝賽寧團隊提出 BLIP3-o:融合自回歸與擴散模型的統一多模態架構,開創CLIP特征驅動的圖像理解與生成新范式

BLIP3-o 是一個統一的多模態模型&#xff0c;它將自回歸模型的推理和指令遵循優勢與擴散模型的生成能力相結合。與之前擴散 VAE 特征或原始像素的研究不同&#xff0c;BLIP3-o 擴散了語義豐富的CLIP 圖像特征&#xff0c;從而為圖像理解和生成構建了強大而高效的架構。 此外還…

HarmonyOs開發之——— ArkWeb 實戰指南

HarmonyOs開發之——— ArkWeb 實戰指南 謝謝關注!! 前言:上一篇文章主要介紹HarmonyOs開發之———合理使用動畫與轉場:CSDN 博客鏈接 一、ArkWeb 組件基礎與生命周期管理 1.1 Web 組件核心能力概述 ArkWeb 的Web組件支持加載本地或在線網頁,提供完整的生命周期回調體…

黑馬程序員C++2024版筆記 第0章 C++入門

1.C代碼的基礎結構 以hello_world代碼為例&#xff1a; 預處理指令 #include<iostream> using namespace std; 代碼前2行是預處理指令&#xff0c;即代碼編譯前的準備工作。&#xff08;編譯是將源代碼轉化為可執行程序.exe文件的過程&#xff09; 主函數 主函數是…

日語學習-日語知識點小記-構建基礎-JLPT-N4階段(22):復習

日語學習-日語知識點小記-構建基礎-JLPT-N4階段(22):復習 1、前言(1)情況說明(2)工程師的信仰2、知識點(1)復習(2)復習3、單詞(1)日語(2)日語片假名單詞4、對話練習5、單詞辨析記錄6、總結1、前言 (1)情況說明 自己在今年,在日本留學中,目前在語言學校,…

Docker配置SRS服務器 ,ffmpeg使用rtmp協議推流+vlc拉流

目錄 演示視頻 前期配置 Docker配置 ffmpeg配置 vlc配置 下載并運行 SRS 服務 推拉流流程實現 演示視頻 2025-05-18 21-48-01 前期配置 Docker配置 運行 SRS 建議使用 Docker 配置 Docker 請移步&#xff1a; 一篇就夠&#xff01;Windows上Docker Desktop安裝 漢化完整指…

Redis——緩存雪崩、擊穿、穿透

緩存雪崩 大量緩存數據在同一時間過期或者Redis故障宕機時&#xff0c;若此時有大量請求&#xff0c;都會直接訪問到數據庫&#xff0c;導致數據庫壓力倍增甚至宕機。 大量數據同時過期解決方案&#xff1a; 1、均勻設置過期時間&#xff1a; 設置過期時間的時候可以追加一…

開源GPU架構RISC-V VCIX的深度學習潛力測試:從RTL仿真到MNIST實戰

點擊 “AladdinEdu&#xff0c;同學們用得起的【H卡】算力平臺”&#xff0c;H卡級別算力&#xff0c;按量計費&#xff0c;靈活彈性&#xff0c;頂級配置&#xff0c;學生專屬優惠。 一、開篇&#xff1a;AI芯片架構演變的三重挑戰 &#xff08;引述TPUv4采用RISC-V的行業案…

字符串相乘(43)

43. 字符串相乘 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a; class Solution { public:string multiply(string num1, string num2) {string res "0";for (int i 0; i < num2.size(); i) {string str multiplyOneNum(num1, num2[num2.size() -…

mathematics-2024《Graph Convolutional Network for Image Restoration: A Survey》

推薦深藍學院的《深度神經網絡加速&#xff1a;cuDNN 與 TensorRT》&#xff0c;課程面向就業&#xff0c;細致講解CUDA運算的理論支撐與實踐&#xff0c;學完可以系統化掌握CUDA基礎編程知識以及TensorRT實戰&#xff0c;并且能夠利用GPU開發高性能、高并發的軟件系統&#xf…

[LevelDB]LevelDB版本管理的黑魔法-為什么能在不鎖表的情況下管理數據?

文章摘要 LevelDB的日志管理系統是怎么通過雙鏈表來進行數據管理為什么LevelDB能夠在不鎖表的情況下進行日志新增 適用人群: 對版本管理機制有開發訴求&#xff0c;并且希望參考LevelDB的版本開發機制。數據庫相關從業者的專業人士。計算機狂熱愛好者&#xff0c;對計算機的…

【C++進階篇】C++容器完全指南:掌握set和map的使用,提升編碼效率

C容器的實踐與應用&#xff1a;輕松掌握set、map與multimap的區別與用法 一. 序列式容器與關聯式容器1.1 序列式容器 (Sequential Containers)1.2 關聯式容器 (Associative Containers) 二. set系列使用2.1 set的構造和迭代器2.2 set的增刪查2.2.1 插入2.2.2 查找2.2.3 刪除 2.…

2_Spring【IOC容器中獲取組件Bean】

Spring中IOC容器中獲取組件Bean 實體類 //接口 public interface TestDemo {public void doSomething(); } // 實現類 public class HappyComponent implements TestDemo {public void doSomething() {System.out.println("HappyComponent is doing something...")…

安卓開飯-ScrollView內嵌套了多個RecyclerView,只想與其中一個RecyclerView有聯動

在 Android 開發中&#xff0c;將 RecyclerView 嵌套在 ScrollView 內通常會導致性能問題和滾動沖突&#xff0c;應盡量避免這種設計。以下是原因和替代方案&#xff1a; 為什么不推薦 RecyclerView ScrollView&#xff1f;?? 性能損耗? RecyclerView 本身已自帶高效回收復…

HTTP 請求中 Content-Type 頭部

HTTP 請求中 Content-Type 頭部可以設置的各種不同的傳輸格式。multipart/form-data 只是其中一種,主要用于傳輸包含文件的數據。 以下是一些常見的 HTTP 請求體的 Content-Type 及其用途: 常見的數據傳輸格式 (Content-Type) 列表: application/json: 描述: 用于傳輸 JSO…

【U-boot 命令使用】

文章目錄 1 查詢有哪些命令2 信息查詢命令dbinfo - 查看板子信息printenv- 輸出環境變量信息version - 輸出uboot版本信息 3 環境變量操作命令修改環境變量新建環境變量刪除環境變量 4 內存操作命令md命令nm命令mm命令mv命令cp命令cmp命令 5 網絡操作命令與網絡有關的環境變量p…

初學者如何用 Python 寫第一個爬蟲?

初學者如何用 Python 寫第一個爬蟲&#xff1f; 一、爬蟲的基本概念 &#xff08;一&#xff09;爬蟲的定義 爬蟲&#xff0c;英文名為 Web Crawler&#xff0c;也被叫做網絡蜘蛛、網絡機器人。想象一下&#xff0c;有一個勤勞的小蜘蛛&#xff0c;在互聯網這個巨大的蜘蛛網中…

IDE/IoT/搭建物聯網(LiteOS)集成開發環境,基于 VSCode + IoT Link 插件

文章目錄 概述IDE安裝安裝舊版本VSCode安裝插件安裝問題和解決手動安裝SDK包手動下載依賴工具 IoTLink配置IoTLink Home用戶設置-工具鏈-編譯器用戶設置-工具鏈-構建器用戶設置-工具鏈-燒錄器用戶設置-SDK管理工程設置-SDK配置工程設置-編譯器工程設置-調試器 創建工程Demo 源碼…

深度剖析:Dify+Sanic+Vue+ECharts 搭建 Text2SQL 項目 sanic-web 的 Debug 實戰

目錄 項目背景介紹sanic-web Dify\_service handle\_think\_tag報錯NoneType問題描述debug Dify調用不成功&#xff0c;一直轉圈圈問題描述debug 前端markdown格式只顯示前5頁問題描述debug1. 修改代碼2.重新構建1.1.3鏡像3.更新sanic-web/docker/docker-compose.yaml4. 重新部…

理想AI Talk第二季-重點信息總結

一、TL&#xff1b;DR 理想為什么要做自己的基模&#xff1a;座艙家庭等特殊VLM場景&#xff0c;deepseek/openai沒有解決理想的基模參數量&#xff1a;服務端-300B&#xff0c;VLencoder-32B/3.6B&#xff0c;日常工作使用-300B&#xff0c;VLA-4B為什么自動駕駛可以達成&…

TensorRT

TensorRT 下載 TensorRT 7.1.3.4 TAR壓縮包&#xff0c;解壓到安裝目錄&#xff1a; tar xzvf TensorRT-7.1.3.4.Ubuntu-16.04.x86_64-gnu.cuda-11.0.cudnn8.0.tar.gz 添加 TensorRT lib 到環境變量&#xff1a; gedit ~/.bashrc # 添加 export LD_LIBRARY_PATH$LD_LIBRARY_PAT…