POSIX互斥鎖和條件變量

一.概述

1.POXIS介紹

??POXIS是一種操作系統接口標準,全稱為“可移植操作系統接口”。

它最初由IEEE組織制定,目的是為了使不同的操作系統之間可以互相兼容。POSIX標準定義了一系列API(應用程序接口)和命令行工具,這些API和工具規定了操作系統應該提供哪些功能,并規定了這些功能的調用方式和行為。

POSIX標準包含多個部分,主要涵蓋了文件管理、進程控制、用戶權限、系統調用等方面。

跨平臺特性:為了保證操作系統 API 的相互兼容性制定了 POSIX 標準。目前符合 POSIX 標準協議的操作系統有:UNIX、BSD、Linux、iOS、Android、SylixOS、VxWorks、RTEMS 等。

Windows操作系統支持POSIX。雖然Windows操作系統并不完全符合POSIX標準,但可以通過一些工具和庫來實現POSIX兼容性。這些工具包括Cygwin、MinGW或MSYS等,它們提供了一些POSIX函數和命令,

使得在Windows上開發和運行POSIX兼容的應用程序成為可能。

2.互斥鎖和條件變量都是進程同步機制,通常,互斥鎖是用來對資源加鎖,條件變量用來等待資源,主要包括兩個動作:

??一個線程等待"條件變量的條件成立"而掛起;

另一個線程使"條件成立"(給出條件成立信號);

由于是多線程,為了防止競爭,所以條件量一般和鎖一起使用。

二.POSIX互斥鎖和條件變量

下面均以linux系統下的使用進行舉例;

1.互斥鎖

互斥鎖是一種同步機制,用于確保同一時間只有一個線程可以訪問共享資源。在 C 語言中,互斥鎖可以通過 pthread_mutex_t 類型來表示,并可以通過 pthread_mutex_init() 函數來初始化。

1.1初始化pthread_mutex_init()

pthread_mutex_init() 函數的原型如下:

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);

其中,mutex 是要初始化的互斥鎖,attr 是互斥鎖屬性。pthread_mutex_init() 函數的返回值如下:

0:成功

EAGAIN:系統資源不足

EINVAL:mutex 或 attr 為 NULL

EBUSY:mutex 已被初始化

pthread_mutex_init() 函數的用法如下:

pthread_mutex_t mutex;

pthread_mutex_init(&mutex, NULL);

在上面的代碼中,首先定義了一個互斥鎖 mutex。然后,使用 pthread_mutex_init() 函數初始化互斥鎖。

1.2加鎖pthread_mutex_lock()

pthread_mutex_lock() 函數用于鎖定互斥鎖。當一個線程試圖鎖定一個已經被鎖定的互斥鎖時,該線程將被阻塞,直到互斥鎖被解鎖。 pthread_mutex_lock() 函數的原型如下:

int pthread_mutex_lock(pthread_mutex_t *mutex);

其中,mutex 是要鎖定的互斥鎖。pthread_mutex_lock() 函數的返回值如下:

0:成功

EDEADLK:線程試圖鎖定自己已經持有的互斥鎖

EINVAL:mutex 為 NULL

pthread_mutex_lock() 函數的用法如下:

pthread_mutex_lock(&mutex);

在上面的代碼中,使用 pthread_mutex_lock() 函數鎖定互斥鎖 mutex。

1.3解鎖pthread_mutex_unlock()

pthread_mutex_unlock() 函數用于解鎖互斥鎖。當一個線程解鎖一個互斥鎖時,該互斥鎖將被釋放,并且任何被阻塞的線程都可以繼續執行。 pthread_mutex_unlock() 函數的原型如下:

int pthread_mutex_unlock(pthread_mutex_t *mutex);

其中,mutex 是要解鎖的互斥鎖。 pthread_mutex_unlock() 函數的返回值如下:

0:成功

EINVAL:mutex 為 NULL

pthread_mutex_unlock() 函數的用法如下:

pthread_mutex_unlock(&mutex);

在上面的代碼中,使用 pthread_mutex_unlock() 函數解鎖互斥鎖 mutex。

1.4銷毀pthread_mutex_destroy()

pthread_mutex_destroy() 函數用于銷毀互斥鎖。當一個互斥鎖不再需要時,應該使用 pthread_mutex_destroy() 函數來銷毀它。 pthread_mutex_destroy() 函數的原型如下:

int pthread_mutex_destroy(pthread_mutex_t *mutex);

其中,mutex 是要銷毀的互斥鎖。 pthread_mutex_destroy() 函數的返回值如下:

0:成功

EINVAL:mutex 為 NULL

pthread_mutex_destroy() 函數的用法如下:

pthread_mutex_destroy(&mutex);

在上面的代碼中,使用 pthread_mutex_destroy() 函數銷毀互斥鎖 mutex。

1.5互斥鎖完整實例

#include <pthread.h>

#include <stdio.h>

pthread_mutex_t mutex;

void *thread_function(void *arg) {

??pthread_mutex_lock(&mutex);

??printf("Thread %ld has locked the mutex\n", pthread_self());

??// 訪問共享資源

??printf("Thread %ld has unlocked the mutex\n", pthread_self());

??pthread_mutex_unlock(&mutex);

??return NULL;

}

int main() {

??pthread_t thread1, thread2;

??pthread_mutex_init(&mutex, NULL);

??pthread_create(&thread1, NULL, thread_function, NULL);

??pthread_create(&thread2, NULL, thread_function, NULL);

??pthread_join(thread1, NULL);

??pthread_join(thread2, NULL);

??pthread_mutex_destroy(&mutex);

??return 0;

}

在這個例子中,創建了一個互斥鎖 mutex,并使用 pthread_mutex_init() 函數初始化它。然后,創建了兩個線程,并使用 pthread_mutex_lock() 函數鎖定互斥鎖,然后訪問共享資源。在訪問共享資源之前,打印一條消息,表明線程已經鎖定了互斥鎖。在訪問共享資源之后,打印一條消息,表明線程已經解鎖了互斥鎖。最后,使用 pthread_mutex_unlock() 函數解鎖互斥鎖,并使用 pthread_mutex_destroy() 函數銷毀互斥鎖。

2.條件變量

條件變量是一種同步機制,用于等待某個條件的發生。在 C 語言中,條件變量可以通過 pthread_cond_t 類型來表示,并可以通過 pthread_cond_init() 函數來初始化。

2.1初始化pthread_cond_init()

pthread_cond_init() 函數的原型如下:

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

其中,cond 是要初始化的條件變量,attr 是條件變量屬性。 pthread_cond_init() 函數的返回值如下:

0:成功

EAGAIN:系統資源不足

EINVAL:cond 或 attr 為 NULL

EBUSY:cond 已被初始化

pthread_cond_init() 函數的用法如下:

pthread_cond_t cond;

pthread_cond_init(&cond, NULL);

在上面的代碼中,首先定義了一個條件變量 cond。然后,我們使用 pthread_cond_init() 函數初始化條件變量。

2.2銷毀pthread_cond_destroy()

pthread_cond_destroy() 函數用于銷毀條件變量。當一個條件變量不再需要時,應該使用 pthread_cond_destroy() 函數來銷毀它。 pthread_cond_destroy() 函數的原型如下:

int pthread_cond_destroy(pthread_cond_t *cond);

其中,cond 是要銷毀的條件變量。 pthread_cond_destroy() 函數的返回值如下:

0:成功

EINVAL:cond 為 NULL

pthread_cond_destroy() 函數的用法如下:

pthread_cond_destroy(&cond);

在上面的代碼中,使用 pthread_cond_destroy() 函數銷毀條件變量 cond。

2.3喚醒pthread_cond_signal()

pthread_cond_signal() 函數用于喚醒一個正在等待條件變量的線程。當一個線程調用 pthread_cond_signal() 函數時,該線程將被喚醒,并且可以繼續執行。 pthread_cond_signal() 函數的原型如下:

int pthread_cond_signal(pthread_cond_t *cond);

其中,cond 是要喚醒的條件變量。 pthread_cond_signal() 函數的返回值如下:

0:成功

EINVAL:cond 為 NULL

pthread_cond_signal() 函數的用法如下:

pthread_cond_signal(&cond);

在上面的代碼中,我們使用 pthread_cond_signal() 函數喚醒條件變量 cond。

2.4喚醒所有pthread_cond_broadcast()

pthread_cond_broadcast() 函數用于喚醒所有正在等待條件變量的線程。當一個線程調用 pthread_cond_broadcast() 函數時,所有正在等待該條件變量的線程將被喚醒,并且可以繼續執行。 pthread_cond_broadcast() 函數的原型如下:

int pthread_cond_broadcast(pthread_cond_t *cond);

其中,cond 是要喚醒的條件變量。 pthread_cond_broadcast() 函數的返回值如下:

0:成功

EINVAL:cond 為 NULL

pthread_cond_broadcast() 函數的用法如下:

pthread_cond_broadcast(&cond);

在上面的代碼中,我們使用 pthread_cond_broadcast() 函數喚醒條件變量 cond。

2.5等待pthread_cond_timedwait()

pthread_cond_timedwait() 函數用于等待條件變量的發生。當一個線程調用 pthread_cond_timedwait() 函數時,該線程將被阻塞,直到條件變量發生或超時。

pthread_cond_timedwait() 函數的原型如下:

int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);

其中,cond 是要等待的條件變量,mutex 是要鎖定的互斥鎖,abstime 是超時時間。 pthread_cond_timedwait() 函數的返回值如下:

0:成功

ETIMEDOUT:超時

EINVAL:cond 或 mutex 為 NULL

EDEADLK:線程試圖鎖定自己已經持有的互斥鎖

pthread_cond_timedwait() 函數的用法如下:

pthread_cond_timedwait(&cond, &mutex, &abstime);

在上面的代碼中,我們使用 pthread_cond_timedwait() 函數等待條件變量 cond 的發生。

2.6條件變量完整實例

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#define NUM_THREADS 2

int count = 0;

pthread_mutex_t mutex;

pthread_cond_t cond;

void* thread_func(void* thread_id) {

????int tid = *((int*)thread_id);

????

????pthread_mutex_lock(&mutex);

????

????while (count < tid) {

????????pthread_cond_wait(&cond, &mutex);

????}

????

????printf("Thread %d: Hello, World!\n", tid);

????

????count++;

????

????pthread_cond_broadcast(&cond);

????pthread_mutex_unlock(&mutex);

????

????pthread_exit(NULL);

}

int main() {

????pthread_t threads[NUM_THREADS];

????int thread_ids[NUM_THREADS];

????

????pthread_mutex_init(&mutex, NULL);

????pthread_cond_init(&cond, NULL);

????

????for (int i = 0; i < NUM_THREADS; i++) {

????????thread_ids[i] = i;

????????pthread_create(&threads[i], NULL, thread_func, (void*)&thread_ids[i]);

????}

????

????for (int i = 0; i < NUM_THREADS; i++) {

????????pthread_join(threads[i], NULL);

????}

????

????pthread_mutex_destroy(&mutex);

????pthread_cond_destroy(&cond);

????

????return 0;

}

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

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

相關文章

Mybatis核心問題總結

對MyBatis源碼的理解 ORM框架&#xff1a;CRUD操作 1。SQL解析&#xff1a; 映射文件、注解--》映射器解析 XMLMapperBuilder MapperAnnotationBuilder 2。SQL執行: SqlSession 接口--》Executor --》 SimpleExecutor ReuseExecutor 【Statement--JDBC】 3。結果映射&…

Go語言---Json

JSON (JavaScript Object Notation)是一種比XML 更輕量級的數據交換格式&#xff0c;在易于人們閱讀和編寫的同時&#xff0c;也易于程序解析和生成。盡管JSON是 JavaScript的一個子集&#xff0c;但 JSON采用完全獨立于編程語言的文本格式&#xff0c;且表現為鍵/值對集合的文…

【大模型LLM面試合集】大語言模型架構_layer_normalization

2.layer_normalization 1.Normalization 1.1 Batch Norm 為什么要進行BN呢&#xff1f; 在深度神經網絡訓練的過程中&#xff0c;通常以輸入網絡的每一個mini-batch進行訓練&#xff0c;這樣每個batch具有不同的分布&#xff0c;使模型訓練起來特別困難。Internal Covariat…

【C++高階】高效數據存儲:理解并模擬實現紅黑樹Map與Set

&#x1f4dd;個人主頁&#x1f339;&#xff1a;Eternity._ ?收錄專欄?&#xff1a;C “ 登神長階 ” &#x1f921;往期回顧&#x1f921;&#xff1a;了解 紅黑樹 &#x1f339;&#x1f339;期待您的關注 &#x1f339;&#x1f339; ?模擬實現Map與Set &#x1f4d2;1.…

js ES6 part1

聽了介紹感覺就是把js在oop的使用 作用域 作用域&#xff08;scope&#xff09;規定了變量能夠被訪問的“范圍”&#xff0c;離開了這個“范圍”變量便不能被訪問&#xff0c; 作用域分為&#xff1a; 局部作用域、 全局作用域 1. 函數作用域&#xff1a; 在函數內部聲明的…

爬取天氣數據,利用Pyecharts作輪播圖

爬取網站鏈接&#xff1a;https://lishi.tianqi.com/xiamen/202312.html 爬取了廈門市2023年一整年的天氣數據&#xff0c;包括最高溫&#xff0c;最低溫&#xff0c;天氣&#xff0c;風力風向等 爬蟲代碼&#xff1a; import requests import pandas as pd import csv from…

UML建模案例分析-時序圖和類圖的對應關系

概念 簡單地說&#xff0c;類圖定義了系統中的對象&#xff0c;時序圖定義了對象之間的交互。 例子 一個電子商務系統&#xff0c;會員可通過電子商務系統購買零件。具體功能需求如下&#xff1a; 會員請求結賬時&#xff0c;系統驗證會員的賬戶是否處于登錄狀態&#xff1…

極狐GitLab 17.0 重磅發布,100+ DevSecOps功能更新來啦~【三】

GitLab 是一個全球知名的一體化 DevOps 平臺&#xff0c;很多人都通過私有化部署 GitLab 來進行源代碼托管。極狐GitLab &#xff1a;https://gitlab.cn/install?channelcontent&utm_sourcecsdn 是 GitLab 在中國的發行版&#xff0c;專門為中國程序員服務。可以一鍵式部署…

【基礎篇】1.8 C語言基礎(二)

2.9 預處理指令和宏定義 在STM32開發中,預處理和宏定義常用于配置硬件參數、啟用或禁用特定功能、以及優化代碼以適應不同的硬件配置或應用場景。通過合理地使用預處理和宏定義,我們可以編寫更加靈活、可配置和高效的代碼。 預處理指令如#include、#define等在C語言編程中起…

防火墻圖形化界面策略和用戶認證(華為)

目錄 策略概要認證概要實驗拓撲圖題目要求一要求二要求三要求四要求五要求六 策略概要 安全策略概要&#xff1a; 安全策略&#xff08;Security Policy&#xff09;在安全領域具有雙重含義。宏觀上&#xff0c;安全策略指的是一個組織為保證其信息安全而建立的一套安全需求、…

uniapp 微信小程序接入MQTT

MQTT安裝 前期準備 由于微信小程序需要wss&#xff0c;所以要有域名SSL證書 新建目錄/srv/mosquitto/config&#xff0c;/srv/mosquitto/config/cert 目錄/srv/mosquitto/config中新建配置文件mosquitto.conf&#xff0c;文件內容 persistence true persistence_location /m…

深入探索Apache Flink:流處理的藝術與實踐

在當今的大數據時代&#xff0c;流處理已成為處理實時數據的關鍵技術。Apache Flink&#xff0c;作為一個開源的流處理框架&#xff0c;以其高吞吐量、低延遲和精確一次&#xff08;exactly-once&#xff09;的語義處理能力&#xff0c;在眾多流處理框架中脫穎而出。本文將深入…

在樹莓派設備上導出系統鏡像

鏡像導出 前提條件&#xff1a; 已獲取可以正常使用的設備。已獲取鼠標、鍵盤和電源適配器。已將設備接入可正常使用的網絡。 操作步驟&#xff1a; 連接適配器給設備上電&#xff0c;正常啟動設備&#xff0c;連接鼠標和鍵盤。在終端命令窗格執行如下命令&#xff0c;安裝…

數據模型-ER圖在數據模型設計中的應用

ER圖在數據模型設計中的應用 1. ER圖概述&#xff1a;起源與發展? 實體-關系圖&#xff08;Entity Relationship Diagram&#xff0c;簡稱ER圖&#xff09;起源于1970年代&#xff0c;由Peter Chen首次提出&#xff0c;作為描述數據和信息間關系的圖形化語言。隨著數據庫技術…

[PM]流程與結構設計

流程圖 流程就是為了達到特定目標, 進行的一系列有邏輯性的操作步驟, 由兩個及已上的步驟, 完成一個完整的行為過程, 即可稱為流程, 流程圖就是對這個過程的圖形化展示 分類 業務流程圖 概念: 描述業務流程的一種圖, 通過特定符號和連線表示具體某個業務的處理步驟和過程作…

MyBatis與JDBC相比,有哪些優勢

MyBatis與JDBC&#xff08;Java Database Connectivity&#xff09;相比&#xff0c;在多個方面展現出顯著的優勢。這些優勢使得MyBatis在現代軟件開發中成為一個非常受歡迎的選擇&#xff0c;特別是在處理數據庫交互時。以下是MyBatis相比JDBC的主要優勢&#xff1a; 1. 簡化…

極狐GitLab亮相世界人工智能大會,開啟開源大模型賦能軟件研發新時代

GitLab 是一個全球知名的一體化 DevOps 平臺&#xff0c;很多人都通過私有化部署 GitLab 來進行源代碼托管。極狐GitLab &#xff1a;https://gitlab.cn/install?channelcontent&utm_sourcecsdn 是 GitLab 在中國的發行版&#xff0c;專門為中國程序員服務。可以一鍵式部署…

285個地級市-胡煥庸線數據

全國285個地級市-胡煥庸線數據.zip資源-CSDN文庫 胡煥庸線&#xff1a;中國人口與生態的分界線 胡煥庸線&#xff0c;一條在中國地理學界具有劃時代意義的分界線&#xff0c;由著名地理學家胡煥庸于1935年提出。這條線從黑龍江省的璦琿&#xff08;現黑河市&#xff09;延伸至…

json-server總結

Json-server 是一個專門用于模擬 RESTful API 的工具&#xff0c;它允許前端開發人員在不依賴后端 API 的情況下進行開發&#xff0c;通過本地搭建一個 JSON 服務來快速生成 REST API 風格的后端服務。 一、主要特點與功能 快速搭建&#xff1a;Json-server 使用 JSON 文件作…

HippoRAG如何從大腦獲取線索以改進LLM檢索

知識存儲和檢索正在成為大型語言模型(LLM)應用的重要組成部分。雖然檢索增強生成(RAG)在該領域取得了巨大進步&#xff0c;但一些局限性仍然沒有克服。 俄亥俄州立大學和斯坦福大學的研究團隊推出了HippoRAG&#xff0c;這是一種創新性的檢索框架&#xff0c;其設計理念源于人類…