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

互斥锁实现线程互斥

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

互斥锁的概念

在这里插入图片描述

互斥锁(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的值。

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

wsl安装ubuntu并设置gnome图形界面详细步骤(win11+ubuntu18)

0.前言 wsl确实是个好东西&#xff0c;不过之前配了好几次都没有成功&#xff0c;因为wsl本身确实是有bug。当时配的时候查到GitHub上的一个issue还没被修好。现在重新配一下。 我的环境是Windows11家庭版。区别于win10&#xff0c;win11安装完默认就是wsl2。 1.下载 首先打…

[RPC]:Feign远程调用

文章目录 摘要1 RPC框架-Feign1.1 什么是Feign1.2 Feign解决的问题1.2.1 使用RestTemplate发送远程调用代码1.2.1.1 项目示例调用链路1.2.1.2 代码逻辑1.2.1.3 代码实现1.2.1.4 存在的问题 1.3 Feign如何使用1.3.1 使用逻辑1.3.2 引入依赖1.3.3 启动类添加注释开启feign功能 摘…

3.数据操作

SQL句子中语法格式提示&#xff1a; 1.中括号&#xff08;[]&#xff09;中的内容为可选项&#xff1b; 2.[&#xff0c;...]表示&#xff0c;前面的内容可重复&#xff1b; 3.大括号&#xff08;{}&#xff09;和竖线&#xff08;|&#xff09;表示选择项&#xff0c;在选择…

网络安全|渗透测试入门学习,从零基础入门到精通—渗透中的开发语言

目录 前面的话 开发语言 1、html 解析 2、JavaScript 用法 3、JAVA 特性 4、PHP 作用 PHP 能做什么&#xff1f; 5、C/C 使用 如何学习 前面的话 关于在渗透中需要学习的语言第一点个人认为就是可以打一下HTML&#xff0c;JS那些基础知识&#xff0c;磨刀不误砍柴…

键盘按键事件 通过键盘上下左右按键移动界面上图标

#main.c文件 #include “keyevent.h” #include int main(int argc, char *argv[]) { QApplication a(argc, argv); KeyEvent w; w.show(); return a.exec();} #include “keyevent.h”//头文件 #ifndef KEYEVENT_H #define KEYEVENT_H #include #include #include cl…

机器学习、计算机视觉和深度学习

机器学习、计算机视觉和深度学习 1 什么是机器学习&#xff1f;2 机器学习的类型3 什么是计算机视觉&#xff1f;4 计算机视觉的机器学习应用5 总结参考 这篇博客将简要介绍&#xff1a;机器学习和用于计算机视觉的机器学习。 想象一下&#xff1a;你可以使用人脸检测算法在图…

自定义修改Typora原生默认github风格样式

使用typora的时候&#xff0c;想要自定义一些颜色、字体&#xff0c;或者修改一些设置&#xff0c;这个时候需要修改或者自己编写css文件。 修改涉及的样式&#xff1a; ① 目录 ② 块应用 我还是比较喜欢原生自带的默认样式&#xff08;github样式&#xff09;&#xff0c; 但…

chatgpt赋能python:Python怎么退出程序:让你轻松掌握退出Python程序的方法

Python怎么退出程序&#xff1a;让你轻松掌握退出Python程序的方法 Python是一种功能强大、易于学习且具有广泛应用的编程语言。在Python开发中&#xff0c;经常需要退出程序&#xff0c;以便在不需要时释放内存和其他资源。那么&#xff0c;Python怎么退出程序&#xff1f;本…

【MySQL】从0到1打开数据库管理

目录 前言&#xff1a; 一.认识MySQL 二.安装MySQL数据库 三、启动和停止MySQL服务 3.1启动服务的两种方式 3.2停止服务的两种方式 四.链接客户端 4.1使用自带的命令行窗口 4.2使用系统自带的命令窗口 五.MySQL是存储数据的模型 六.SQL语言 结尾&#xff1a; 前言&a…

HTML(结构)+CSS(样式基础)

一、HTML前期准备 1. 认识HTML HTML&#xff08;Hyper Text Markup Language&#xff09;&#xff1a;超文本标记语言主要通过标签对网页中的文本、图片、音频、视频等内容进行描述个人理解&#xff1a;对所有需要描述的内容使用标签进行表示 2. HTML布置页面的固定结构 每一个…

Baumer工业相机堡盟工业相机如何使用BGAPISDK的相机图像时间戳计算运行时间以及时间差(C#)

Baumer工业相机堡盟工业相机如何使用BGAPISDK的相机图像时间戳计算运行时间以及时间差&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机BGAPI SDK和图像时间戳的技术背景Baumer工业相机使用BGAPISDK控制相机数据流的方式1.引用合适的类文件2.使用BGAPISDK获取时间戳的…

【Java基础学习打卡06】编程语言

目录 前言一、计算机语言是什么&#xff1f;二、计算机语言分类三、计算机语言介绍1.C语言2.C语言3.Java语言4.Python语言 总结 前言 本文主要是理解计算机语言是什么&#xff0c;有哪些分类&#xff0c;分类下有哪些编程语言&#xff0c;以及了解主流的编程语言。 一、计算机…

【Kubernetes存储篇】常见存储方案及场景分析

文章目录 一、持久化存储理论1、为什么要做数据持久化存储&#xff1f;2、常见持久化存储方案 二、案例&#xff1a;持久化存储方案1、emptydir临时存储卷2、hostPath本地存储卷3、NFS网络共享存储卷 一、持久化存储理论 官方中文参考文档&#xff1a; 1、为什么要做数据持久…

CloudQuery一体化数据库SQL操作安全管控平台

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; CloudQuery一体化数据库SQL操作安全管控平台 导读 CloudQuery作为业界领先的面向企业的数据库安全解决方案&#xff0c;CloudQuery致力于打造一站式安全可靠的数据操…

开源赋能,决胜未来 — 参加原子全球开源峰会有感

目录 文章目录 目录前言开源决胜未来&#xff1a;闭源摧毁 UNIX&#xff0c;开源成就 Linux开源创新&#xff1a;软硬件协同&#xff0c;共建开源生态 前言 开源原子基金会作为国内首家开源基金会组织&#xff0c;由其主办的首届 “开放原子全球开源峰会” 也是第一次被冠以 “…

软件测试工程师如何从功能测试转成自动化测试

功能测试转成自动化测试&#xff0c;答案就三个字&#xff1a;“靠学习”。 学习自动化的方法无非是三种&#xff1a; 一、靠培训&#xff08;下方有如何选择培训机构&#xff09; 在相对有氛围的学习环境中来学习自动化测试&#xff0c;这是一个较快学习的方法。二、靠自学自…

2023年网络安全竞赛——网络安全应急响应Server2228

网络安全应急响应 任务环境说明&#xff1a; 服务器场景&#xff1a;Server2228&#xff08;开放链接&#xff09; 用户名&#xff1a;root&#xff0c;密码&#xff1a;pssw0rd123 1. 找出被黑客修改的系统别名&#xff0c;并将倒数第二个别名作为Flag值提交&#xff1b…

大数据Doris(四十四):kafka json 数组格式数据导入到Doris

文章目录 kafka json 数组格式数据导入到Doris 一、创建 Doris 表 二、创建 Kafka topic

Appium知多少

Appium我想大家都不陌生&#xff0c;这是主流的移动自动化工具&#xff0c;但你对它真的了解么&#xff1f;为什么很多同学搭建环境时碰到各种问题也而不知该如何解决。 appium为什么英语词典查不到中文含义&#xff1f; appium是一个合成词&#xff0c;分别取自“applicatio…

知识图谱实战应用16-知识图谱在化学物质结构上的应用,快速查找化学分子式与结构

大家好,我是微学AI,今天给大家介绍一下知识图谱实战应用16-知识图谱在化学物质结构上的应用,快速查找化学分子式与结构。在化学领域,知识图谱可以应用于化学物质结构上。化学物质结构主要指分子结构和化学键的组成情况。知识图谱可以将化学物质结构的相关数据以图谱的形式展…