進程間通信——信號量

進程間通信——信號量

目錄

一、基本概念?

1.1 概念

1.2 基本操作

1.3?相關函數

1.3.1 semget創建/獲取

1.3.2 semop操作信號量

1.3.3 semctl初始化/刪除

二、代碼操作

2.1 不用PV的

2.2 用PV 的

2.2.1 a.c

2.2.2 b.c

2.2.3 sem.h

?2.2.4 sem.c


一、基本概念?

1.1 概念

信號量本質上是一個計數器,用于記錄可用資源的數量。它有兩種類型的操作:P 操作(也稱為 wait 操作)和 V 操作(也稱為 signal 操作)。P 操作會將信號量的值減 1,表示請求一個資源V 操作會將信號量的值加 1,表示釋放一個資源

當信號量的值為 0 時,表示沒有可用資源,此時進程在請求資源時會被阻塞,直到其他進程釋放資源。

臨界資源:同一時刻只允許一個進程訪問的資源

臨界區:訪問臨界資源的代碼段。這段代碼執行了就會訪問例如打印機之類的臨界資源

1.2 基本操作

初始化:在使用信號量之前,需要對其進行初始化,設置初始值。這個值通常表示系統中某種資源的初始數量。
P 操作:當一個進程需要訪問共享資源時,它首先執行 P 操作。如果信號量的值大于 0,那么 P 操作會成功執行,進程可以繼續執行并使用資源,同時信號量的值減 1。如果信號量的值為 0,那么進程會被阻塞,放入與該信號量相關的等待隊列中,直到其他進程執行 V 操作釋放資源。
V 操作:當進程使用完共享資源后,它執行 V 操作。V 操作會將信號量的值加 1,如果有其他進程在等待該資源(即信號量的等待隊列不為空),那么系統會從等待隊列中喚醒一個進程,讓它繼續執行 P 操作以獲取資源。

1.3?相關函數

1.3.1 semget創建/獲取

semget?函數用于創建一個新的信號量集或獲取一個已存在的信號量集的標識符

#include <sys/sem.h>int semget(key_t key, int nsems, int semflg);
  • key:一個鍵值,用于標識信號量集。可以使用?ftok?函數生成一個唯一的鍵值,也可以使用特殊值?IPC_PRIVATE?來創建一個私有的信號量集,該信號量集只能由創建它的進程及其子進程訪問。
  • nsems:指定信號量集中信號量的數量。如果是創建新的信號量集,必須指定該值;如果是獲取已存在的信號量集,該值通常為 0。
  • semflg:標志位,用于指定創建信號量集的模式和權限等。常見的標志有:
    • IPC_CREAT:如果信號量集不存在,則創建它。
    • IPC_EXCL:與?IPC_CREAT?一起使用,若信號量集已存在,則返回錯誤。
    • 權限標志,如?0666?表示所有用戶都有讀寫權限。
  • 成功時,返回一個非負整數,即信號量集的標識符(semid)。
  • 失敗時,返回 -1,并設置?errno?來指示錯誤類型。

1.3.2 semop操作信號量

semop?函數用于對信號量集中的一個或多個信號量進行操作,如 P 操作(申請資源)和 V 操作(釋放資源)

#include <sys/sem.h>int semop(int semid, struct sembuf *sops, unsigned nsops);
  • semid:信號量集的標識符,由?semget?函數返回。
  • sops:指向一個?struct sembuf?結構體數組的指針,每個?struct sembuf?結構體描述了對一個信號量的操作。struct sembuf?結構體的定義如下:
  • struct sembuf {unsigned short sem_num;  // 信號量在信號量集中的索引(從 0 開始)short          sem_op;   // 操作類型,正數表示釋放資源(V 操作),負數表示申請資源(P 操作),0 表示等待信號量值為 0short          sem_flg;  // 標志位,常見的有 IPC_NOWAIT 表示非阻塞操作
    };
  • nsopssops?數組中元素的數量,即要執行的操作數量。

1.3.3 semctl初始化/刪除

semctl?函數用于對信號量集進行控制操作,如初始化信號量的值、獲取信號量的狀態信息、刪除信號量集等。

#include <sys/sem.h>int semctl(int semid, int semnum, int cmd, ...);
  • semid:信號量集的標識符,由?semget?函數返回。
  • semnum:信號量在信號量集中的索引(從 0 開始)。如果?cmd?不需要指定特定的信號量,則該值通常為 0。
  • cmd:要執行的控制命令,常見的命令有:
    • SETVAL:設置指定信號量的值,需要傳遞一個?int?類型的參數作為新值。
    • GETVAL:獲取指定信號量的值,返回值即為信號量的當前值。
    • IPC_RMID:刪除信號量集,不需要指定?semnum,也不需要額外的參數。
  • ...:可變參數,根據?cmd?的不同而有所不同。例如,當?cmd?為?SETVAL?時,需要傳遞一個?int?類型的參數作為新的信號量值。
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "sem.h"int main()
{sem_init(); // 創建并初始化信號量for(int i=0; i<5; i++){sem_p();printf("A");fflush(stdout);int n = rand() % 3; // 隨機睡眠一段時間sleep(n);printf("A");fflush(stdout);sem_v();n = rand() % 3;sleep(n);}sleep(10);sem_destroy(); // 刪除信號量
}

二、代碼操作

2.1 不用PV的

a.c

#include <stdio.h>
#include <string.h>
#include <unistd.h>int main()
{for(int i=0;i<5;i++){printf("A");fflush(stdout);int n=rand()%3;sleep(n);printf("A");fflush(stdout);}
}

b.c

#include <stdio.h>
#include <string.h>
#include <unistd.h>int main()
{for(int i=0;i<5;i++){printf("B");fflush(stdout);int n=rand()%3;sleep(n);printf("B");fflush(stdout);}
}

?

  1. /a &./b&?:在后臺同時運行可執行文件?a?和?b?,[1] 10916?和?[2] 10917?分別是這兩個后臺進程的作業編號和進程號。

2.2 用PV 的

2.2.1 a.c

a.c使用信號量進行進程同步的C語言程序示例。

它演示了如何使用信號量來控制對共享資源的訪問,以防止數據競爭和條件競爭

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "sem.h"int main()
{sem_init();//創建并初始化信號量//pfor(int i = 0; i < 5; i++ ){sem_p();printf("A");fflush(stdout);int n = rand() % 3;sleep(n);printf("A");fflush(stdout);sem_v();n = rand()%3;sleep(n);}//vsleep(10);sem_destroy();//刪除信號量
}

2.2.2 b.c

?b.c它演示了如何使用信號量來控制對共享資源的訪問。

在這個例子中,程序通過信號量來確保在打印字符'B'時不會有多個線程或進程同時執行,從而避免輸出混亂。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "sem.h"
int main()
{sem_init();for(int i = 0; i < 5; i++ ){sem_p();printf("B");fflush(stdout);int n = rand() % 3;sleep(n);printf("B");fflush(stdout);sem_v();n = rand()%3;sleep(n);}}

2.2.3 sem.h

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/sem.h>union semun
{int val;
};void sem_init();
void sem_p();
void sem_v();
void sem_destroy();

定義了一組與信號量操作相關的函數原型和一個用于信號量操作的聯合體semun

這個聯合體用于在信號量操作中傳遞信號量的值

這些函數原型定義了信號量操作的接口,下面是這些函數可能的實現方式:

  1. sem_init:初始化信號量。

  2. sem_p:執行信號量的P操作(wait操作),減少信號量的值,如果信號量的值小于0,則進程將被阻塞。

  3. sem_v:執行信號量的V操作(signal操作),增加信號量的值,如果有進程因等待此信號量而被阻塞,則它們可能會被喚醒。

  4. sem_destroy:銷毀信號量,釋放相關資源。

?2.2.4 sem.c

信號量操作實現

#include "sem.h"
static int semid = -1;void sem_init()
{semid = semget((key_t)1234,1,IPC_CREAT|IPC_EXCL|0600);//嘗試創建一個新的信號了if( semid == -1 )//信號量可能存在{semid = semget((key_t)1234,1,0600);if( semid == -1){printf("sem err\n");return;}}else//初始化 1{union semun a; a.val = 1;if( semctl(semid,0,SETVAL,a) == -1){printf("semctl err\n");}}
}
void sem_p()
{struct sembuf buf;buf.sem_num = 0;buf.sem_op = -1;//pbuf.sem_flg = SEM_UNDO;//if( semop(semid,&buf,1) == -1)//可能阻塞{printf("p err\n");}}
void sem_v()
{struct sembuf buf;buf.sem_num = 0;buf.sem_op = 1;//vbuf.sem_flg = SEM_UNDO;//if( semop(semid,&buf,1) == -1){printf("v err\n");}
}
void sem_destroy()
{if( semctl(semid,0,IPC_RMID) == -1){printf("rm semid err\n");}
}

sem_init?函數?初始化一個信號量

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

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

相關文章

Linux內核2-TFTP與NFS環境搭建

Uboot&#xff1a;引導程序 初始化硬件設備&#xff0c;初始化c語言環境&#xff0c;為內核加載做準備 zImage:內核文件 rootfs:文件系統&#xff0c;為用戶提供一個與硬件設備數據交互的系統 1.TFTP和NFS功能 TFTP:簡單文件傳輸協議網絡配置 pc可以下載 2.minicom bootargs…

TDengine 中的命名與邊界

簡介 本章主要介紹命名的合法字符集和限制規則&#xff0c;這對于正確使用 TDengine&#xff0c;減小報錯很重要&#xff0c;這些規則在 SQL 語句中都生效&#xff0c;在使用過程中要注意&#xff0c;避免不必要的錯誤。 名稱命名規則 合法字符&#xff1a;英文字符、數字和…

C++ 中將函數作為參數傳遞

C 中將函數作為參數傳遞 1. 通過指針傳遞函數 函數可以通過傳遞函數的地址來作為參數傳遞&#xff1b;簡而言之&#xff0c;就是通過指針實現這一點。 示例代碼 #include <iostream> using namespace std;// 定義加法和減法函數 #include <iostream> #include …

Vala 編程語言教程-繼承

繼承? 在 Vala 中&#xff0c;一個類可以繼承自 ?一個或零個? 其他類。盡管實際開發中通常繼承一個類&#xff08;不同于 Java 等語言的隱式繼承機制&#xff09;&#xff0c;但 Vala 并不強制要求必須繼承。 當定義繼承自其他類的子類時&#xff0c;子類的實例與父…

Crypto Architecture Kit簡介

HarmonyOS 5.0.3(15) 版本的配套文檔&#xff0c;該版本API能力級別為API 15 Release 文章目錄 約束與限制能力范圍基本概念與相關Kit的關系 Crypto Architecture Kit屏蔽了第三方密碼學算法庫實現差異的算法框架&#xff0c;提供加解密、簽名驗簽、消息驗證碼、哈希、安全隨機…

交流電機類型及其控制技術

交流電機可分為同步電機和異步電機兩大種類&#xff0c;如果電機轉子的轉速與定子旋轉磁場的轉速相等&#xff0c;轉子與定子旋轉磁場在空間同步地旋轉&#xff0c;這種電機就稱為同步電機。如果電機轉子的轉速不等于定子旋轉磁場的轉速&#xff0c;轉子與定子旋轉磁場在空間旋…

SQL語言分類及命令詳解(一)

目錄 1. DQL&#xff08;Data Query Language&#xff09;數據查詢語言 主要命令&#xff1a; SELECT 2. DDL&#xff08;Data Definition Language&#xff09;數據定義語言 主要命令&#xff1a; CREATE ALTER DROP TRUNCATE&#xff08;清空表數據&#xff0c;保留…

fluent_UDF學習筆記

UDF源代碼路徑 D:\Program Files\ANSYS Inc\v231\fluent\fluent23.1.0\src關于顆粒反彈速度的計算 /* 通過面法向單位向量計算速度的法向向量、切向向量&#xff0c;再通過法向、切向恢復系數重新計算反彈速度*//* Compute normal velocity.將顆粒速度向面法線方向投影&#x…

Go 語言標準庫中sort模塊詳細功能介紹與示例

Go語言的 sort 模塊提供了對切片和自定義數據結構的排序功能&#xff0c;支持基本類型排序、自定義排序規則、穩定排序和二分查找。以下是 sort 模塊的核心方法及示例說明&#xff1a; 1. 基本類型排序 sort.Ints、sort.Float64s、sort.Strings 直接對基本類型的切片進行排序…

第十六屆藍橋杯模擬二(串口通信)

由硬件框圖可以知道我們要配置LED 和按鍵 一.LED 先配置LED的八個引腳為GPIO_OutPut,鎖存器PD2也是,然后都設置為起始高電平,生成代碼時還要去解決引腳沖突問題 二.按鍵 按鍵配置,由原理圖按鍵所對引腳要GPIO_Input 生成代碼,在文件夾中添加code文件夾,code中添加fun.…

06-ADC

ADC簡介 Analog-Digital Converter 模擬-數字轉換器 ADC可以將引腳上連續變化的模擬電壓轉換為內存中存儲的數字變量&#xff0c;建立模擬電路到數字電路的橋梁。 12位逐次逼近型ADC&#xff0c;1us轉換時間&#xff1b;輸入電壓范圍&#xff1a;0-3.3V&#xff0c;轉換結果…

二層綜合實驗

拓撲圖 實驗要求 1.內網IP地址使用172.16.6.0/16分配 2.sw1和sW2之間互為備份 3.VRRP/STP/VLAN/Eth-trunk均使用 4.所有Pc均通過DHCP獲取IP地址 5.ISP只能配置IP地址 6.所有電腦可以正常訪問IsP路由器環回 實驗思路 這是一個二層綜合實驗每當拿到一個實驗看清楚要求之后都有…

Java實現pdf中動態插入圖片

今天接到一個需求&#xff0c;需要在pdf中的簽名處&#xff0c;插入簽名照片&#xff0c;但簽名位置不固定&#xff0c;話不多說上代碼&#xff1a; 1、首先引入itextpdf依賴包&#xff1a; <dependency><groupId>com.itextpdf</groupId><artifactId>…

OpenCV 圖形API(2)為什么需要圖形API?

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 G-API背后的動機 G-API模塊為OpenCV帶來了基于圖的執行模型。本章簡要描述了這種新模型如何在兩個方面幫助軟件開發者&#xff1a;優化和移植圖像處理算法…

基于Spring AI開發本地Jenkins MCP Server服務

前言 首先介紹下MCP是什么&#xff1f; MCP是由開發了 Claude 模型的 Anthropic 公司2024年12月提出并開源的一項開放標準&#xff0c;全稱&#xff1a;Model Context Protocol&#xff0c;它是一個開放協議&#xff0c;它使 LLM 應用與外部數據源和工具之間的無縫集成成為可能…

vcpkg安裝指定版本的庫

一.vcpkg安裝 使用git將vcpkg源碼克隆到本地制定目錄&#xff08;D:\vcpkg&#xff09;&#xff0c;并初始化 git clone https://github.com/microsoft/vcpkg.git cd vcpkg ./bootstrap-vcpkg.sh # Linux/macOS .\bootstrap-vcpkg.bat # Windows 如下圖&#xff1a; 二.安…

數據結構C語言練習(單雙鏈表)

本篇練習題(單鏈表)&#xff1a; 1.力扣 203. 移除鏈表元素 2.力扣 206. 反轉鏈表 3.力扣 876. 鏈表的中間結點 4.力扣 21. 合并兩個有序鏈表 5. 牛客 鏈表分割算法詳解 6.牛客 鏈表回文結構判斷 7. 力扣 160. 相交鏈表 8. 力扣 141 環形鏈表 9. 力扣 142 環形鏈表 II…

nginx部署前端項目(linux、docker)

引言 在CentOS 7系統上使用docker安裝nginx&#xff0c;使用nginx部署一個由Vue開發、打包的項目 docker安裝nginx 這里不多贅述&#xff0c;直接上docker-compose.yml代碼 nginx:container_name: nginximage: nginx:1.27.2ports:- "80:80"volumes:- /docker/ngin…

WPF ContentPresenter詳解2

ContentPresenter與ContentControl的區別 ContentControl 和 ContentPresenter 是 WPF 中兩個相關的控件&#xff0c;但它們在用途和功能上有一些關鍵的區別。理解這兩者的區別和聯系有助于更好地設計和開發用戶界面。 1. 類層次結構 ContentControl&#xff1a;位于 WPF 控件…

【HTML5游戲開發教程】零基礎入門合成大西瓜游戲實戰 | JS物理引擎+Canvas動畫+完整源碼詳解

《從咖啡杯到財務自由&#xff1a;一個程序員的合成之旅——當代碼遇上物理引擎的匠心之作》 &#x1f31f; 這是小游戲開發系列的第四篇送福利文章&#xff0c;感謝一路以來支持和關注這個項目的每一位朋友&#xff01; &#x1f4a1; 文章力求嚴謹&#xff0c;但難免有疏漏之…