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.mzph.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;其设计理念源于人类…