信號量主要API及綜合應用

1.信號量概述

信號量是一個底層核心模塊【int】類型變量,記錄當前信號量數據。

信號量 P 操作 (sem_wait)

????????線程檢測對應信號量底層 int 數據數值,如果大于 0,當前線程獲得 CPU 執行權,同時將信號量底層 int 數據-1 操作。

如果底層數據為 0,當前線程無法獲取 CPU 執行權,進入阻塞狀態。同時等待信號量 > 0

信號量 V 操作 (sem_post)

????????線程任務執行完畢,執行 V 操作,對當信號量底層 int 數據 +1,相當于釋放 CPU 執行權。

信號量可以控制線程互斥和線程同步。

2.信號量相關API

2.1sem_init初始化

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

函數功能:

????????用于初始化一個信號量變量,提供必要的參數,限制當前信號量是針對于【線程操作】還是【進程操作】

函數參數:

????????sen_t *sem:?信號量變量地址

????????int? pshared:?控制值當前信號量,限制內容為線程還是進程,線程參數要求為 0, 不等于 0 為進程間操作。建議 0 線程, 1 進程。

????????unsigned int value:?信號量初始化數據,通常情況下為 1?

返回值:

????????成功返回 0

????????失敗返回 -1

2.2sem_wait? ?P操作/等待操作

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

函數功能:

????????信號量 P 操作,當前信號量-1。

????????如果為 0 當前線程/進程進入阻塞狀態。

????????如果不為 0,信號量 -= 1,同時可以執行目標線程/進程代碼。

函數參數:

????????sem_t *sem:?信號量變量地址

返回值類型:

????????成功返回 0

????????失敗返回 -1

2.3sem_post? V操作/釋放操作

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

函數功能:

????????信號量 V 操作,當前信號量 +1

????????信號量不為 0,相當于解除與當前信號量相關的其他線程/進程阻塞狀態

函數參數:

????????sem_t *sem :?信號量變量地址

返回值類型

????????成功返回 0

????????失敗返回 -1

2.4sem_destroy? 銷毀操作

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

函數功能:

????????銷毀當前信號量變量

函數參數:

????????sem_t? *sem:?信號量變量地址

返回值類型

????????成功返回 0

????????失敗返回 -1

2.5信號量的操作案例

將上面的信號量函數進行綜合應用

2.5.1信號量互斥控制

相當于互斥鎖的作用

#define _POSIX_C_SOURCE 200112L
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h>
#include <semaphore.h>
sem_t sem;
void *threadA_task(void *arg);
void *threadB_task(void *arg);
void *threadC_task(void *arg);
void print_string(const char *str);
// 線程 A 對應的線程【句柄】類型
pthread_t tid1;
// 線程 B 對應的線程【句柄】類型
pthread_t tid2;
// 線程 C 對應的線程【句柄】類型
pthread_t tid3;
int main(int argc, char const *argv[])
{int status = 0;/*1. 初始化信號量初始化當前信號量,對應的控制目標為線程,初始化數據為 1int sem_init (sem_t *__sem, int __pshared, unsigned int __value)*/status = sem_init(&sem, 0, 3);//int? pshared:?控制值當前信號量,限// 制內容為線程還是進程,線程參數要求為 0, //不等于 0 為進程間操作。建議 0 線程, 1 進程。if (status){printf("semaphore init failed!\n");_exit(1);}status = pthread_create(&tid1, NULL, threadA_task, "Hello World!");if (status){printf("pthread_create threadA failed!\n");_exit(1);}status = pthread_create(&tid2, NULL, threadB_task, "Hello HH!");if (status){printf("pthread_create threadB failed!\n");_exit(1);}status = pthread_create(&tid3, NULL, threadC_task, "Hello GL!");if (status){printf("pthread_create threadC failed!\n");_exit(1);}pthread_join(tid1, NULL);pthread_join(tid2, NULL);pthread_join(tid3, NULL);return 0;
}
void *threadA_task(void *arg)
{// 信號量 P 操作sem_wait(&sem);print_string((const char *)arg);// 信號量 V 操作sem_post(&sem);
}
void *threadB_task(void *arg)
{// 信號量 P 操作sem_wait(&sem);print_string((const char *)arg);// 信號量 V 操作sem_post(&sem);
}
void *threadC_task(void *arg)
{// 信號量 P 操作sem_wait(&sem);print_string((const char *)arg);// 信號量 V 操作sem_post(&sem);
}
void print_string(const char *str)
{while (*str){printf("%c\n", *str);sleep(1);str += 1;}
}

2.5.1信號量執行流程控制

#define _POSIX_C_SOURCE 200112L
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h>
#include <semaphore.h>
sem_t sem1;
sem_t sem2;
sem_t sem3;
void *threadA_task(void *arg);
void *threadB_task(void *arg);
void *threadC_task(void *arg);
void print_string(const char *str);
// 線程 A 對應的線程【句柄】類型
pthread_t tid1;
// 線程 B 對應的線程【句柄】類型
pthread_t tid2;
// 線程 C 對應的線程【句柄】類型
pthread_t tid3;
int main(int argc, char const *argv[])
{int status = 0;/*1. 初始化信號量初始化當前信號量,對應的控制目標為線程,初始化數據為 1int sem_init (sem_t *__sem, int __pshared, unsigned int __value)*/status = sem_init(&sem1, 0, 1);if (status){printf("semaphore init failed!\n");_exit(1);}status = sem_init(&sem2, 0, 0);if (status){printf("semaphore init failed!\n");_exit(1);}status = sem_init(&sem3, 0, 0);if (status){printf("semaphore init failed!\n");_exit(1);}status = pthread_create(&tid1, NULL, threadA_task, "Hello World!");if (status){printf("pthread_create threadA failed!\n");_exit(1);}status = pthread_create(&tid2, NULL, threadB_task, "Hello HH!");if (status){printf("pthread_create threadB failed!\n");_exit(1);}status = pthread_create(&tid3, NULL, threadC_task, "Hello GL!");if (status){printf("pthread_create threadC failed!\n");_exit(1);}pthread_join(tid1, NULL);pthread_join(tid2, NULL);pthread_join(tid3, NULL);// 線程銷毀pthread_cancel(tid1);pthread_cancel(tid2);pthread_cancel(tid3);// 信號量銷毀sem_destroy(&sem1);sem_destroy(&sem2);sem_destroy(&sem3);return 0;
}
void *threadA_task(void *arg)
{// sem1 信號量 P 操作sem_wait(&sem1);print_string((const char *)arg);// sem2 信號量 V 操作sem_post(&sem2);
}
void *threadB_task(void *arg)
{// sem2 信號量 P 操作sem_wait(&sem2);print_string((const char *)arg);// sem3 信號量 V 操作sem_post(&sem3);
}
void *threadC_task(void *arg)
{// sem3 信號量 P 操作sem_wait(&sem3);print_string((const char *)arg);// sem1 信號量 V 操作sem_post(&sem1);
}
void print_string(const char *str)
{printf("%s\n", str);sleep(5);
}

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

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

相關文章

工業自動化領域的“超級跑車”:西門子TDC系統深度解析與實戰架構

工業自動化領域的“超級跑車”&#xff1a;西門子TDC系統深度解析與實戰架構 文章目錄 工業自動化領域的“超級跑車”&#xff1a;西門子TDC系統深度解析與實戰架構引言&#xff1a;當普通PLC遇到性能瓶頸第一章&#xff1a;認識TDC——它不是簡單的“大型PLC”1.1 TDC究竟是什…

MySQL高階查詢語句與視圖實戰指南

MySQL高階查詢語句與視圖實戰指南 文章目錄MySQL高階查詢語句與視圖實戰指南一、常用高階查詢技巧1. 按關鍵字排序&#xff08;ORDER BY&#xff09;基礎用法進階用法&#xff1a;多字段排序條件過濾2. 區間判斷與去重&#xff08;AND/OR DISTINCT&#xff09;區間判斷&#x…

解決Pytest參數化測試中文顯示亂碼問題:兩種高效方法

在使用Pytest進行參數化測試時&#xff0c;許多開發者都會遇到一個常見但令人頭疼的問題&#xff1a;當測試用例的ids參數包含中文字符時&#xff0c;控制臺輸出會出現亂碼。這不僅影響了測試報告的可讀性&#xff0c;也給測試結果的分析帶來了困難。本文將深入探討這個問題&am…

基于SpringBoot的校園流浪動物救助平臺【spring boot實戰項目、Java畢設、Java項目、Java實戰】

&#x1f496;&#x1f496;作者&#xff1a;計算機畢業設計小途 &#x1f499;&#x1f499;個人簡介&#xff1a;曾長期從事計算機專業培訓教學&#xff0c;本人也熱愛上課教學&#xff0c;語言擅長Java、微信小程序、Python、Golang、安卓Android等&#xff0c;開發項目包括…

利用kimi k2編寫postgresql協議服務端的嘗試

美團龍貓還是很有自知之明的 提問請用C編寫postgresql協議服務端&#xff0c;能接收psql客戶端或其他采用postgresql協議的工具的請求&#xff0c;實現將用戶請求打印在控制臺&#xff0c;并把回應發給客戶端回答 抱歉&#xff0c;我無法為您編寫完整的 PostgreSQL 協議服務端。…

醫療 AI 再突破:輔助診斷準確率超 90%,但落地醫院仍面臨數據安全與臨床信任難題

一、引言&#xff08;一&#xff09;醫療 AI 發展背景在數字化與智能化浪潮的席卷下&#xff0c;醫療領域正經歷著深刻變革&#xff0c;人工智能&#xff08;AI&#xff09;技術的融入成為這場變革的關鍵驅動力。近年來&#xff0c;醫療 AI 輔助診斷技術取得重大突破&#xff0…

Rocky Linux10.0安裝zabbix7.4詳細步驟

安裝Rocky Linux10.0系統 請參考Rocky Linux10.0安裝教程-CSDN博客 查看當前系統版本 cat /etc/*release 安裝數據庫 安裝zabbix之前&#xff0c;需要先安裝一個數據庫來承載zabbix的數據。這里我選擇在本機直接安裝一個MariaDB數據庫。 Rocky Linux10.0系統默認不包含MySQ…

JDBC插入數據

文章目錄視頻&#xff1a;JDBC插入數據環境準備寫插入數據屬性配置屬性配置視頻&#xff1a;JDBC插入數據 環境準備 MySQL環境 小皮面板 提供MySQL環境 寫插入數據 屬性配置 聲明變量 屬性配置 # . properties 是一個特俗的map 集合 # key : 字符串 value : 字符串…

GPU 服務器壓力測試核心工具全解析:gpu-burn、cpu-burn 與 CUDA Samples

在 GPU 服務器的性能驗證、穩定性排查與運維管理中,壓力測試是關鍵環節,可有效檢測硬件極限性能、散熱效率及潛在故障。以下從工具原理、核心功能、使用場景等維度,詳細介紹三款核心測試工具,幫助用戶系統掌握 GPU 服務器壓力測試方法。 一、GPU 專屬壓力測試工具:gpu-bu…

Python進程和線程——多線程

前面提到過進程是由很多線程組成的&#xff0c;那么今天廖老師就詳細解釋了線程是如何運行的。首先&#xff0c;&#xff0c;Python的標準庫提供了兩個模塊&#xff1a;_thread和threading&#xff0c;_thread是低級模塊&#xff0c;threading是高級模塊&#xff0c;對_thread進…

【MySQL|第九篇】視圖、函數與優化

目錄 十、視圖 1、簡單視圖&#xff1a; 2、復雜視圖&#xff1a; 3、視圖更新&#xff1a; 十一、函數 1、函數創建&#xff1a; 十二、數據庫優化 1、索引優化&#xff1a; 2、查詢優化&#xff1a; 3、設計優化&#xff1a; 十、視圖 在 MySQL 中&#xff0c;視圖…

使用Docker和虛擬IP在一臺服務器上靈活部署多個Neo4j實例

使用Docker和虛擬IP在一臺服務器上靈活部署多個Neo4j實例 前言 在現代應用開發中&#xff0c;圖數據庫Neo4j因其強大的關系處理能力而備受青睞。但有時候我們需要在同一臺服務器上運行多個Neo4j實例&#xff0c;比如用于開發測試、多租戶環境或者A/B測試。傳統的端口映射方式…

K8s學習筆記(一):Kubernetes架構-原理-組件

Kubernetes&#xff08;簡稱 K8s&#xff09;是一款開源的容器編排平臺&#xff0c;核心目標是實現容器化應用的自動化部署、擴展、故障恢復和運維管理。其設計遵循 “主從架構”&#xff08;Control Plane Node&#xff09;&#xff0c;組件分工明確&#xff0c;通過 “聲明式…

ensp配置學習筆記 比賽版 vlan 靜態路由 ospf bgp dhcp

學習配置VLAN 虛擬局域網&#xff0c;目的讓兩臺在同一網段的設備&#xff0c;在交換機中訪問。基礎指令&#xff1a;sys 進入系統 sysname R1 修改交換機名字為R1 display cur 查看數據、端口等交換機信息 &#xff08;在端口中&#xff0c;可以直接display this 可以直接看…

倉頡編程語言青少年基礎教程:enum(枚舉)類型和Option類型

倉頡編程語言青少年基礎教程&#xff1a;enum&#xff08;枚舉&#xff09;類型和Option類型enum 和 Option 各自解決一類“語義級”問題&#xff1a;enum 讓“取值只在有限集合內”的約束從注釋變成編譯器強制&#xff1b;Option 讓“值可能不存在”的語義顯式化。enum類型enu…

javaEE-Spring IOCDI

目錄 1、什么是Spring&#xff1a; 2.什么是IoC: 3. 什么是控制反轉呢? 4.IoC容器具備以下優點: 5.DI是什么&#xff1a; 依賴注?方法&#xff1a; 三種注入方法的優缺點&#xff1a; Autowired注解注入存在的問題&#xff1a; Autowired和Resource的區別&#xff…

TensorFlow Lite 全面解析:端側部署方案與PyTorch Mobile深度對比

1 TensorFlow Lite 基礎介紹 TensorFlow Lite (TFLite) 是 Google 為移動設備&#xff08;Android, iOS&#xff09;、微控制器&#xff08;Microcontrollers&#xff09;和其他嵌入式設備&#xff08;如 Raspberry Pi&#xff09;開發的輕量級深度學習推理框架。它的核心目標是…

mapbox進階,使用jsts實現平角緩沖區

????? 主頁: gis分享者 ????? 感謝各位大佬 點贊?? 收藏? 留言?? 加關注?! ????? 收錄于專欄:mapbox 從入門到精通 文章目錄 一、??前言 1.1 ??mapboxgl.Map 地圖對象 1.2 ??mapboxgl.Map style屬性 1.3 ??jsts myBufferOp 緩沖區生成對對象 …

linux裝好顯卡后如何檢查

背景&#xff1a;客戶通知裝好了顯卡&#xff0c;我們去機器上查看一下一. 使用到的命令 watch -n 1 nvidia-smi 可實時查看gpu的使用率nvidia-smi 之查看一次 二、查看內存和顯存 內存使用命令 free -h,顯存使用 nvidia-smi 這只是查看的navidia, 其他品牌的會不一樣

人工智能深度學習——卷積神經網絡(CNN)

一、圖像卷積運算 對圖像矩陣與濾波器矩陣進行對應相乘再求和運算&#xff0c;轉化得到新的矩陣。 作用&#xff1a;快速定位圖像中某些邊緣特征 英文&#xff1a;convolution&#xff08;CNN&#xff09;池化層實現維度縮減 池化&#xff1a;按照一個固定規則對圖像矩陣進行處…