互斥锁实现线程互斥(嵌入式学习)

news2024/12/28 3:51:10

互斥锁实现线程互斥

  • 互斥锁的概念
  • 互斥锁的函数
  • 示例代码

互斥锁的概念

在这里插入图片描述

互斥锁(Mutex)是一种用于多线程编程的同步原语(synchronization primitive),用于实现线程之间的互斥访问共享资源。互斥锁提供了一种机制,确保在任何给定时间点只有一个线程可以访问临界区(Critical Section)。

临界区是指一段代码或数据,它被多个线程共享,并且在任何给定时间只能由一个线程执行或访问,以避免竞争条件(Race Condition)和数据不一致的问题。

互斥锁具备两种状态:已锁定(locked)和未锁定(unlocked)。当一个线程获得了互斥锁的锁定状态时,其他试图获取该互斥锁的线程将被阻塞,直到持有锁的线程释放互斥锁。

互斥锁的常见操作包括两个主要函数:

  1. 加锁(Lock):当一个线程进入临界区前,通过调用加锁函数来获取互斥锁的锁定状态。如果互斥锁已经被其他线程锁定,那么当前线程将被阻塞,直到互斥锁可用。

  2. 解锁(Unlock):当一个线程执行完临界区的代码后,通过调用解锁函数来释放互斥锁,使其变为未锁定状态,从而允许其他线程获取该锁。

互斥锁的作用是确保在临界区内只有一个线程在执行,从而保证共享资源的正确性和一致性。当多个线程需要访问共享资源时,通过使用互斥锁来对临界区进行保护,可以有效避免数据竞争和并发访问问题,保证线程安全性。

需要注意的是,互斥锁并不保证公平性,即无法确保线程获取锁的顺序。因此,在编写多线程程序时,应谨慎设计临界区的大小和持锁时间,以避免潜在的性能问题和死锁(Deadlock)情况的发生。

互斥锁的函数

在这里插入图片描述

使用互斥锁(Mutex)需要调用一系列相关函数来进行初始化、加锁、解锁和销毁等操作。下面是互斥锁相关函数的详细解释:

  1. pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t* attr)

    • 该函数用于初始化互斥锁。
    • 参数:
      • mutex:指向要初始化的互斥锁变量的指针。
      • attr:指向互斥锁属性的指针,通常为NULL,表示使用默认属性。
    • 返回值:若成功则返回0,否则返回错误码。
  2. pthread_mutex_lock(pthread_mutex_t* mutex)

    • 该函数用于加锁互斥锁。
    • 参数:
      • mutex:指向要加锁的互斥锁变量的指针。
    • 返回值:若成功则返回0,否则返回错误码。如果互斥锁已经被锁定,调用线程将被阻塞,直到互斥锁可用。
  3. pthread_mutex_unlock(pthread_mutex_t* mutex)

    • 该函数用于解锁互斥锁。
    • 参数:
      • mutex:指向要解锁的互斥锁变量的指针。
    • 返回值:若成功则返回0,否则返回错误码。如果调用该函数时线程没有持有互斥锁,将导致未定义的行为。
  4. pthread_mutex_trylock(pthread_mutex_t* mutex)

    • 该函数尝试加锁互斥锁,如果互斥锁已经被锁定,则立即返回失败,不会阻塞线程。
    • 参数:
      • mutex:指向要尝试加锁的互斥锁变量的指针。
    • 返回值:若成功则返回0,表示已经获得互斥锁;若失败则返回EBUSY,表示互斥锁已经被锁定。
  5. pthread_mutex_destroy(pthread_mutex_t* mutex)

    • 该函数用于销毁互斥锁。
    • 参数:
      • mutex:指向要销毁的互斥锁变量的指针。
    • 返回值:若成功则返回0,否则返回错误码。销毁一个正在被其他线程锁定的互斥锁是未定义的行为。

这些函数都需要包含头文件pthread.h。在使用互斥锁时,通常需要定义一个pthread_mutex_t类型的变量作为互斥锁对象,并在适当的位置调用上述函数来进行初始化、加锁、解锁和销毁操作,以确保线程的互斥访问和共享资源的正确性。

示例代码

在这里插入图片描述

以下是一个使用互斥锁实现线程互斥的示例:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

// 全局变量作为共享资源
int shared_variable = 0;
pthread_mutex_t mutex; // 定义互斥锁

// 线程函数
void* thread_function(void* arg) {
    int i;
    for (i = 0; i < 1000000; i++) {
        pthread_mutex_lock(&mutex); // 加锁

        // 访问共享资源
        shared_variable++;
        
        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);

    // 输出结果
    printf("Shared variable value: %d\n", shared_variable);

    return 0;
}

在上面的示例中,使用了pthread_mutex_t类型的变量mutex来表示互斥锁。在thread_function线程函数中,首先使用pthread_mutex_lock函数对互斥锁进行加锁操作,以确保只有一个线程可以访问临界区(在这里是shared_variable)。然后,在访问完共享资源后,使用pthread_mutex_unlock函数对互斥锁进行解锁操作。

main函数中,创建了两个线程thread1thread2,它们会并发地访问临界区。最后,使用pthread_join函数等待线程结束,并在程序最后输出shared_variable的值。

通过使用互斥锁,可以确保线程对共享资源的互斥访问,从而避免竞争条件和数据不一致的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/656392.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

限流式保护器在高校中的应用

安科瑞虞佳豪 4月10日下午1点50多分 浙大紫金港校区边一活动板房发生火情。起火位置为浙大紫金港校区的动物保护基地。 “起火的地方是有一个学生动物保护者协会&#xff0c;里面有一些学生救助的猫、狗等小动物。”一位学校的学生告诉潮新闻记者。 随后&#xff0c;潮新闻…

C语言(14) 谈谈嵌入式 C 语言踩内存问题!

1 概述 C 语言内存问题&#xff0c;难在于定位&#xff0c;定位到了就好解决了。 这篇笔记我们来聊聊踩内存。踩内存&#xff0c;通过字面理解即可。本来是操作这一块内存&#xff0c;因为设计失误操作到了相邻内存&#xff0c;篡改了相邻内存的数据。 踩内存&#xff0c;轻则…

Shopify股价在暴涨了78%以后,还值得投资吗?

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 今年以来Shopify (SHOP)的股价一直在上涨&#xff0c;迄今为止的涨幅已经超过了78%&#xff0c;并且远远跑赢了美股的所有主要指数。 猛兽财经认为&#xff0c;Shopify的股价之所以能在今年上涨&#xff0c;主要受到以下几…

windows2022证书配置.docx

Windows证书的配置 要求两台主机&#xff0c;一台作为域&#xff0c;一台进入域 按要求来选择角色服务 确认之后安装 安装完以后配置证书服务 选择服务 按要求配置 注&#xff1a;此处不用域用户登陆无法使用企业CA 按要求来 创建新的私钥 这几处检查无误后默认即可 有效期…

实验篇(7.2) 16. 站对站安全隧道 - 通过聚合隧道走对方上网(FortiGate-IPsec) ❀ 远程访问

【简介】前面所有实验基本上是由向导来完成的&#xff0c;只有隧道聚合实验是手动设置的。那么远程访问经常用到的走对方宽带上网功能&#xff0c;需要怎样手动配置呢&#xff1f; 实验要求与环境 OldMei集团深圳总部防火墙现在有三条宽带了&#xff0c;二条普通宽带用来上网及…

SSCMS 内容管理系统介绍

概述 SSCMS 内容管理系统基于微软 .NET Core 平台开发,用于创建在 Windows、Linux、Mac 以及 Docker 上运行的 Web 应用程序和服务。 SSCMS 针对企业级客户开发,完全开源免费,可以用于商业用途不需要支付任何产品或授权费用。 SSCMS 经受了时间考验,1.0 版本在2003年发布…

跨模态检索最新高质量综述《Image-text Retrieval: A Survey on Recent Research and Development》

Image-text Retrieval: A Survey on Recent Research and Development 图像文本检索研究进展综述 2022.03 本文已把文献的引用逐个换成相应的论文标题&#xff0c;方便查找和阅读 摘要 本文从四个方面对ITR方法进行了全面和最新的调查。通过将ITR系统剖析为两个过程&#xff1…

基于Java+Swing+Mysql实现汽车信息管理系统

基于JavaSwingMysql实现汽车信息管理系统 一、系统介绍二、功能展示1.登陆2.车辆信息3.车辆入库4.车辆出库5.车辆查询6、车辆信息修改 三、数据库四、其它1.其他系统实现五.获取源码 一、系统介绍 系统实现汽车入库&#xff0c;汽车出库&#xff0c;汽车查询&#xff0c;汽车信…

2023软件测试八股文最全文档,再也不用担心面试了

前言 6月份已经快过完一半了&#xff0c;马上就要到金九银十的黄金招聘季节了&#xff0c;还在准备面试跳槽涨薪的小伙伴们可以看看本篇文章哟&#xff0c;这里呢笔者就不多说废话了直接上干货&#xff01;答案已整理好&#xff0c;文末拿去即可&#xff01;非常好用&#xff…

day57_Git

今日内容 零、 复习昨日 零、 复习昨日 文章目录 零、 复习昨日一、引言二、介绍三、Git安装3.1 下载Git3.2 安装3.3 基本配置3.4 测试 四、架构五、仓库5.1 新建仓库5.2 工作区5.3 暂存区5.4 分支 六、基本操作6.1 查看仓库状态6.2 暂存文件6.3 提交文件6.4 撤销已经add的文件…

POSTGRESQL PG_GATHER 如何单纯用SQL 就可以产生一个有意思的PG 的分析报告

开头还是介绍一下群&#xff0c;如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;在新加的朋友会分到2群&#xff08;共…

【Android开发基础】Canvas画笔(以刮刮乐为例)

文章目录 一、引言二、设计1、获取图片资源2、获取屏幕信息3、Canvas涂层4、随机内容5、屏幕监听 三、附件1、UI设计2、总代码&#xff08;1&#xff09;控件初始化&#xff08;2&#xff09;图层初始化 3、源代码 一、引言 &#xff08;本篇博客只说明Canvas画笔的使用&#…

STM32单片机(六)TIM定时器 -> 第六节:TIM输入捕获练习(输入捕获模式测频率和PWMI模式测频率占空比)

❤️ 专栏简介&#xff1a;本专栏记录了从零学习单片机的过程&#xff0c;其中包括51单片机和STM32单片机两部分&#xff1b;建议先学习51单片机&#xff0c;其是STM32等高级单片机的基础&#xff1b;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 &#xff1a;适用于想要…

docker inspect

docker inspect 命令用于获取有关 Docker 容器、镜像、网络等的详细信息。它提供了关于指定对象的元数据和配置的完整视图&#xff0c;包括运行状态、网络设置、卷挂载、环境变量等。 以下是一些常见的字段和属性&#xff0c;可以根据需要选择其中一些或全部列出&#xff1a; …

【算法与数据结构】202、LeetCode快乐数

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;先用一个dowhile循环计算整数各个位数字的平方和&#xff0c;然后在unordered_set里面插入n&#xff0…

C语言学习笔记:函数

✨博文作者&#xff1a;烟雨孤舟 &#x1f496; 喜欢的可以 点赞 收藏 关注哦~~ ✍️ 作者简介: 一个热爱大数据的学习者 ✍️ 笔记简介&#xff1a;作为大数据爱好者&#xff0c;以下是个人总结的学习笔记&#xff0c;如有错误&#xff0c;请多多指教&#xff01; 目录 简介 …

关于OpenCV中minAreaRect角度记录

一、问题引出 最近看到stackflow关于minAreaRect的讨论&#xff1a; MinAreaRect angles - Unsure about the angle returnedOpenCV’s RotatedRect angle does not provide enough information 大概问题是minAreaRect这个接口返回的角度信息不足以反应返回的旋转矩形的旋转…

appium辅助自动化工具-- Appium studio

这里我要给大家介绍一款appium辅助自动化测试工具appium studio&#xff0c;你没看错&#xff0c;不是android studio&#xff0c;也不是appium android studio&#xff0c;就是appium studio&#xff01; 下载地址&#xff1a; Appium Studio | Digital.ai Continuous Test…

架构-计算机体系结构

章节架构 分值约 3 分 #mermaid-svg-nV7dvQlYnuXaOVOf {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-nV7dvQlYnuXaOVOf .error-icon{fill:#552222;}#mermaid-svg-nV7dvQlYnuXaOVOf .error-text{fill:#552222;strok…

如何优雅的使用 React Context

在开始今天的文章之前&#xff0c;大家不妨先想一下触发 React 组件 re-render 的原因有哪些&#xff0c;或者说什么时候 React 组件会发生 re-render 。 先说结论&#xff1a; 状态变化父组件 re-renderContext 变化Hooks 变化 ❝ 这里有个误解&#xff1a;props 变化也会导致…