当前位置: 首页 > news >正文

Linux下的线程同步与死锁避免

文章目录

      • 死锁的四个必要条件
      • 破坏死锁条件的方法
        • 破坏互斥条件
          • 使用读写锁(`pthread_rwlock_t`)
        • 破坏持有并等待条件
          • 一次性申请所有资源
        • 破坏不可剥夺条件
          • 使用超时锁定机制
          • 可重入锁(递归锁)
        • 破坏循环等待条件
          • 统一锁顺序

在 Linux 下进行多线程编程时,线程同步是至关重要的部分,尤其是在多个线程需要共享资源的场景中。尽管同步机制能够解决竞争条件,但它也带来了死锁的风险。死锁是指多个线程互相等待对方释放锁而导致永远无法继续执行的现象。为了避免死锁,可以从破坏导致死锁的四个必要条件入手。本文将从这四个条件展开,探讨如何通过破坏这些条件来避免死锁。


死锁的四个必要条件

根据操作系统中的经典理论,死锁的产生必须满足以下四个必要条件:

  1. 互斥条件:某些资源是只能被一个线程独占使用的。
  2. 持有并等待条件:一个线程已经持有了某个资源,同时它在等待获取其他线程持有的资源。
  3. 不可剥夺条件:已经获得的资源不能被强行剥夺,线程只能主动释放资源。
  4. 循环等待条件:存在一个线程循环等待的链,链中的每个线程都在等待下一个线程持有的资源。

为了避免死锁,可以通过破坏至少其中一个条件来打破死锁局面。下面,我们将详细探讨这四个条件以及如何在 Linux 下的线程同步机制中破坏这些条件来避免死锁。


破坏死锁条件的方法

破坏互斥条件

互斥条件是指某些资源只能被一个线程独占使用,无法同时被多个线程访问。在某些情况下,我们可以通过将资源转换为可共享的资源来破坏互斥条件,从而避免死锁。

使用读写锁(pthread_rwlock_t

读写锁允许多个线程同时读取数据,而只有在写操作时需要独占锁。这种机制可以提高并发性,避免因读操作而产生死锁。

pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;void* reader(void* arg) {pthread_rwlock_rdlock(&rwlock); // 获取读锁// 执行读操作pthread_rwlock_unlock(&rwlock); // 释放锁return NULL;
}void* writer(void* arg) {pthread_rwlock_wrlock(&rwlock); // 获取写锁// 执行写操作pthread_rwlock_unlock(&rwlock); // 释放锁return NULL;
}

通过使用读写锁,我们可以允许多个线程并发读取数据,从而减少死锁的可能性。


破坏持有并等待条件

持有并等待条件指的是一个线程持有一个资源,同时等待其他资源的情况。为了避免这种情况,我们可以在申请资源之前,确保线程不占有其他资源,或者一次性申请所有所需资源。

一次性申请所有资源

如果线程需要多个资源,可以采用一次性申请所有资源的策略。即,线程只有在能够获取所有资源时才会继续执行,否则会释放已经持有的资源,避免持有并等待的发生。

pthread_mutex_t lock1, lock2;void* task(void* arg) {// 一次性申请所有资源if (pthread_mutex_trylock(&lock1) == 0) {if (pthread_mutex_trylock(&lock2) == 0) {// 执行任务pthread_mutex_unlock(&lock2);}pthread_mutex_unlock(&lock1);}return NULL;
}

通过一次性申请资源,线程要么成功获取所有资源并继续执行,要么立即释放资源,减少持有并等待的风险。


破坏不可剥夺条件

不可剥夺条件是指资源一旦被线程占有,其他线程就无法强制剥夺。我们可以引入超时机制或设计自愿释放机制来打破这一条件。

使用超时锁定机制

我们可以通过使用 pthread_mutex_trylock() 或在某些高级锁机制中使用超时锁定机制,让线程在等待资源时不会无限期等待。如果线程无法在规定的时间内获得资源,它可以选择放弃并执行其他操作。

pthread_mutex_t lock;void* task(void* arg) {if (pthread_mutex_trylock(&lock) == 0) {// 成功获取锁,执行任务pthread_mutex_unlock(&lock);} else {// 获取锁失败,执行其他操作或等待一段时间后重试}return NULL;
}

通过这种方式,线程不会无限期地等待资源,从而避免了死锁的发生。

可重入锁(递归锁)

递归锁(pthread_mutex_t 使用 PTHREAD_MUTEX_RECURSIVE 属性初始化)允许同一线程多次锁定同一个互斥锁,而不发生死锁。当线程完成任务后,它需要相应次数地解锁。

pthread_mutex_t recursive_mutex;pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&recursive_mutex, &attr);

递归锁通过允许同一线程多次锁定相同的资源,避免了某些递归调用中的死锁风险。


破坏循环等待条件

循环等待条件是指存在一个线程循环等待链,每个线程都在等待下一个线程持有的资源。我们可以通过强制规定获取锁的顺序来打破循环等待。

统一锁顺序

为避免循环等待,所有线程都应按照相同的顺序请求资源。例如,如果所有线程都按顺序 lock1 -> lock2 -> lock3 获取锁,便不会产生循环等待。

pthread_mutex_t lock1, lock2;void* task1(void* arg) {pthread_mutex_lock(&lock1); // 按照固定顺序加锁pthread_mutex_lock(&lock2);// 执行任务pthread_mutex_unlock(&lock2);pthread_mutex_unlock(&lock1);
}void* task2(void* arg) {pthread_mutex_lock(&lock1); // 同样的顺序pthread_mutex_lock(&lock2);// 执行任务pthread_mutex_unlock(&lock2);pthread_mutex_unlock(&lock1);
}

通过保持锁的获取顺序一致,线程避免了陷入循环等待,从而有效地防止死锁。

相关文章:

Linux下的线程同步与死锁避免

文章目录 死锁的四个必要条件破坏死锁条件的方法破坏互斥条件使用读写锁(pthread_rwlock_t) 破坏持有并等待条件一次性申请所有资源 破坏不可剥夺条件使用超时锁定机制可重入锁(递归锁) 破坏循环等待条件统一锁顺序 在 Linux 下进…...

【Python爬虫实战】Selenium自动化网页操作入门指南

#1024程序员节|征文# 🌈个人主页:易辰君-CSDN博客 🔥 系列专栏:https://blog.csdn.net/2401_86688088/category_12797772.html ​ 目录 前言 一、准备工作 (一)安装 Selenium 库 &#xff0…...

mono源码交叉编译 linux arm arm64全过程

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…...

矩阵的可解性:关于Ax=b的研究

上一篇文章讲解了如何求解 A x 0 Ax0 Ax0,得到 A A A的零空间。 类似的,我们今天学习的是如何求解 A x b Axb Axb,并以此加强你对线性代数中,代数与空间的理解。 同样的,我们举与上一次一样的例子,矩阵 …...

10.22.2024刷华为OD C题型(三)--for循环例子

脚踝动了手术,现在宾馆恢复,伤筋动骨一百天还真不是说笑的,继续努力吧。 文章目录 靠谱的车灰度图恢复灰度图恢复 -- for循环使用例子 靠谱的车 https://www.nowcoder.com/discuss/564514429228834816 这个题目思路不难,就是要自…...

QT:MaintenanceTool 模块安装工具

QT的MaintenanceTool 工具对已安装的 Qt 进行卸载、修复等其他操作时提示At least one valid and enabled repository required for this action to succeed 解决方式:在设置中添加一个临时的仓库 https://mirrors.tuna.tsinghua.edu.cn/qt/online/qtsdkrepositor…...

同标签实现监听LocalStorage

使用 React 生命周期函数 useEffect来监听和处理 LocalStorage 的变化 import React, { useEffect } from react;const LocalStorageListener () > {useEffect(() > {// 注册监听器const handleStorageChange (event) > {if (event.key myKey) {console.log(注册…...

JAVA高性能缓存项目

版本一 代码实现 import java.util.HashMap; import java.util.concurrent.TimeUnit;public class CacheExample01 {private final static HashMap<String, Integer> cache new HashMap<>();public static Integer check(String userId) throws InterruptedExce…...

智慧农业大数据平台:智汇田园,数驭未来

智慧农业大数据平台 计讯物联智慧农业大数据平台是一个集管理数字化、作业自动化、生产智能化、产品绿色化、环境信息化、服务现代化于一体的多功能监管系统。它通过与硬件产品的搭配使用&#xff0c;实现对农业生产全过程的实时监测、精准控制和科学管理。该平台集成了多个数…...

Go语言基础教程:可变参数函数

Go 语言允许函数接收可变数量的参数&#xff0c;这种特性对于处理数量不确定的参数特别有用。在本教程中&#xff0c;我们将通过示例代码讲解如何定义和使用 Go 的可变参数函数。 package mainimport "fmt"// 定义一个可变参数函数 sum&#xff0c;接收任意数量的整…...

高并发场景下解决并发数据不一致

简单的场景: 全量数据更新的情况下, 不在乎同一秒的请求都必须要成功, 只留下最新的更新请求数据 方案常用的是 1、数据库增加时间戳标识实现的乐观锁, 请求参数从源头带上微秒或者毫秒时间戳数据库存储, 然后在更新SQL语句上比较 (数据库的时间 < 参数传递的时间) 例如: A…...

OpenAI GPT-o1实现方案记录与梳理

本篇文章用于记录从各处收集到的o1复现方案的推测以及介绍 目录 Journey Learning - 上海交通大学NYUMBZUAIGAIRCore IdeaKey QuestionsKey TechnologiesTrainingInference A Tutorial on LLM Reasoning: Relevant methods behind ChatGPT o1 - UCL汪军教授Core Idea先导自回归…...

Excel:vba实现生成随机数

Sub 生成随机数字()Dim randomNumber As IntegerDim minValue As IntegerDim maxValue As Integer 设置随机数的范围(假入班级里面有43个学生&#xff0c;学号是从1→43)minValue 1maxValue 43 生成随机数(在1到43之间生成随机数)randomNumber Application.WorksheetFunctio…...

Python | Leetcode Python题解之第506题相对名次

题目&#xff1a; 题解&#xff1a; class Solution:desc ("Gold Medal", "Silver Medal", "Bronze Medal")def findRelativeRanks(self, score: List[int]) -> List[str]:ans [""] * len(score)arr sorted(enumerate(score), …...

安全见闻(6)

声明&#xff1a;学习视频来自b站up主 泷羽sec&#xff0c;如涉及侵权马上删除文章 感谢泷羽sec 团队的教学 视频地址&#xff1a;安全见闻&#xff08;6&#xff09;_哔哩哔哩_bilibili 学无止境&#xff0c;开拓自己的眼界才能走的更远 本文主要讲解通讯协议涉及的安全问题。…...

Promise、async、await 、异步生成器的错误处理方案

1、Promise.all 的错误处理 Promise.all 方法接受一个 Promise 数组&#xff0c;并返回所有解析 Promise 的结果数组&#xff1a; const promise1 Promise.resolve("one"); const promise2 Promise.resolve("two");Promise.all([promise1, promise2]).…...

腾讯云:数智教育专场-学习笔记

15点13分2024年10月21日&#xff08;短短5天的时间&#xff0c;自己的成长速度更加惊人&#xff09;-开始进行“降本增效”学习模式&#xff0c;根据小米手环对于自己的行为模式分析&#xff08;不断地寻找数据之间的关联性&#xff09;&#xff0c;每天高效记忆时间&#xff0…...

Ovis: 多模态大语言模型的结构化嵌入对齐

论文题目&#xff1a;Ovis: Structural Embedding Alignment for Multimodal Large Language Model 论文地址&#xff1a;https://arxiv.org/pdf/2405.20797 github地址&#xff1a;https://github.com/AIDC-AI/Ovis/?tabreadme-ov-file 今天&#xff0c;我将分享一项重要的研…...

python的Django的render_to_string函数和render函数模板的使用

一、render_to_string render_to_string 是 Django 框架中的一个便捷函数&#xff0c;用于将模板渲染为字符串。 render_to_string(template_name.html, context, requestNone, usingNone) template_name.html&#xff1a;要渲染的模板文件的名称。context&#xff1a;传递给…...

基于Python大数据的王者荣耀战队数据分析及可视化系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…...

WikiJS全文搜索实战:用ElasticSearch+IK分词器提升内容检索效率(Docker版)

WikiJS全文搜索实战&#xff1a;ElasticSearch与IK分词器的深度优化指南 引言&#xff1a;为什么需要专业级全文搜索解决方案&#xff1f; 想象一下&#xff0c;当你面对一个包含数千篇技术文档的Wiki系统时&#xff0c;传统的关键词匹配就像在黑暗房间里寻找一根针。WikiJS自带…...

centos7安装MySQL8.4手册

目录前言一、首先更新插件&#xff0c;并查看当前系统版本二、安装步骤--在线安装1、创建mysql目录2、安装rpm包3、安装 mysql-community-server4、启动MySQL服务5、查看MySQL状态6、设置开机自启动三、查看默认密码四、登录mysql五、修改密码六、开启远程访问1. 修改 MySQL 配…...

5年java开发经验总结面试题-内含完整答案

1、讲讲IO里面的常见类&#xff0c;字节流、字符流、接口、实现类、方法阻塞。 文件字节输入输出流 FileInputStream/FileOutputStream&#xff0c; 文件字符流 FileReader/FileWriter 包装流PrintStream/PrintWriter/Scanner 字符串输入输出流StringReader/StringWriter 转换流…...

基于西门子PLC的矿井通风控制系统(含IO表、PLC引脚图、程序) PLC程序设计,价格便宜

基于西门子PLC的矿井通风控制系统&#xff08;含IO表、PLC引脚图、程序&#xff09; PLC程序设计&#xff0c;价格便宜&#xff0c;plc触摸屏上位机程序设计&#xff0c;编写。 西门子plc仿真程序设计 提供程序说明&#xff0c; plc程序代写 PLC程序设计、代做 图片为案例 接设…...

基于SpringBoot+Vue的疫情物资管理系统管理系统设计与实现【Java+MySQL+MyBatis完整源码】

摘要 近年来&#xff0c;全球范围内突发公共卫生事件频发&#xff0c;疫情物资的高效管理与调配成为保障社会稳定的重要环节。传统物资管理方式依赖人工操作&#xff0c;存在效率低、数据不透明、响应速度慢等问题&#xff0c;难以满足紧急情况下的物资调度需求。尤其在新冠疫情…...

告别重复造轮子,用快马ai一键生成tomcat高效开发工具集与配置模板

今天想和大家分享一个提升Tomcat开发效率的小技巧。作为一个经常和Tomcat打交道的开发者&#xff0c;我发现每次新建项目都要重复写一些基础工具类&#xff0c;特别浪费时间。最近在InsCode(快马)平台上尝试用AI生成了一套可复用的工具集&#xff0c;效果很不错。 数据库连接池…...

网易云音乐评论数据分析:用Python爬取+可视化热门歌曲情感倾向

网易云音乐评论数据挖掘&#xff1a;从爬取到情感分析的完整实战指南 音乐平台的用户评论蕴含着丰富的情感价值和商业洞察。作为国内领先的音乐社区&#xff0c;网易云音乐的海量评论数据对产品经理优化功能、市场人员分析用户偏好具有重要价值。本文将系统性地介绍如何通过Pyt…...

3种激活方案:解决IDM弹窗问题的开源工具应用指南

3种激活方案&#xff1a;解决IDM弹窗问题的开源工具应用指南 【免费下载链接】IDM-Activation-Script IDM Activation & Trail Reset Script 项目地址: https://gitcode.com/gh_mirrors/id/IDM-Activation-Script 一、问题溯源&#xff1a;解析IDM激活弹窗的技术本质…...

数据稠密计算的算法优化:从理论到实践

数据稠密计算的算法优化&#xff1a;从理论到实践 引言 作为一名在数据深渊里捞了十几年 Bug 的女码农&#xff0c;我见过太多因为算法选择不当导致的性能问题。在数据稠密计算中&#xff0c;算法的选择和优化是提升计算性能的关键因素之一。今天&#xff0c;我们来聊聊数据稠密…...

收藏!小白也能看懂的大模型如何改写工业效率?

收藏&#xff01;小白也能看懂的大模型如何改写工业效率&#xff1f; 本文介绍了中控技术的TPT大模型在工业生产中的应用&#xff0c;它通过实时监控、自动计算最优参数和风险预警&#xff0c;帮助企业提升效率、降低成本。与互联网领域的AI应用不同&#xff0c;工业AI的价值更…...