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

Linux -- 死锁、自旋锁

目录

死锁

概念

死锁的四个必要条件

避免死锁的发生

自旋锁

概念

pthread_spin_init(初始化自旋锁)

pthread_spin_lock(申请自旋锁)

pthread_spin_unlock(释放自旋锁)

pthread_spin_destroy(销毁自旋锁)


死锁

概念

死锁(Deadlock)是指两个或多个进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,这些进程将无法继续推进。

举例来说,现在有线程 A 和线程 B,这两个线程都需要同时持有互斥锁 1 和互斥锁 2 才可以向后推进,访问临界资源,此时 线程 A 拿到了互斥锁 1,线程 B 拿到了互斥锁 2,两个线程都申请对方持有的锁,但是谁都不肯释放锁,导致谁都无法同时持有两把锁,那么这两个线程就互相等待,都不向后推进了,导致死锁!

死锁的四个必要条件

  1. 互斥条件:一个资源每次只能被一个执行流使用。
  2. 占有并等待条件:一个进程必须已经持有至少一个资源,并等待获取当前被其他进程占用的额外资源。
  3. 不可剥夺条件:资源不能从进程那里强行夺取,只有拥有该资源的进程可以主动释放资源。
  4. 循环等待条件:若干执行流之间形成一种头尾相连的循环等待资源的关系。即存在一组等待的进程{P1, P2, ..., PN},其中每个Pi正在等待由Pi+1持有的资源,PN等待由P1持有的资源。

避免死锁的发生

  • 只要破坏死锁的四个必要条件之一,就可以避免死锁!
  • 尽量缩短持有锁的时间,只在绝对必要的时候才获取锁,并尽快释放。
  • 确保所有线程总是按照相同的顺序获取锁,以防止循环等待。
  • 要求每个进程在开始执行之前一次性申请所有需要的资源。这种方法可以完全避免死锁,但可能导致资源利用率低下。

自旋锁

概念

自旋锁(Spinlock)是一种同步机制,主要用于多处理器系统中保护共享资源。与传统的互斥锁不同,当一个线程尝试获取已经被占用的自旋锁时,它不会立即进入睡眠状态(阻塞),而是会不停地循环检查锁的状态(忙等待或自旋),直到锁被释放。这种方式可以减少上下文切换带来的开销,但在锁持有时间较长的情况下,可能会浪费大量的CPU周期。

自旋锁最适合用于锁持有时间非常短暂的情形,例如保护少量数据或执行简单操作时。在这些情况下,上下文切换的成本可能超过自旋等待的成本。此外,在实时系统中,为了确保响应时间尽可能短,也常常使用自旋锁。

pthread_spin_init(初始化自旋锁)

#include <pthread.h>

int pthread_spin_init(pthread_spinlock_t *lock, int pshared);

lock:指向要初始化的自旋锁对象的指针

pshared:指示该自旋锁是否可以在进程间共享。取值有两种:

  • PTHREAD_PROCESS_PRIVATE (0):默认值,表示该锁只能被同一进程内的线程共享
  • PTHREAD_PROCESS_SHARED (非0):表示该锁可以被多个进程中的线程共享。

返回值

  • 成功时返回 0
  • 如果发生错误,则返回一个正整数错误码,并且不会初始化自旋锁。

pthread_spin_lock(申请自旋锁)

#include <pthread.h>

int pthread_spin_lock(pthread_spinlock_t *lock);

lock: 指向要获取的自旋锁对象的指针。

返回值:

  • 成功时返回 0
  • 如果发生错误,则返回一个正整数错误码。

pthread_spin_unlock(释放自旋锁)

#include <pthread.h>

int pthread_spin_unlock(pthread_spinlock_t *lock);

 lock: 指向要释放的自旋锁对象的指针。

返回值:

  • 成功时返回 0
  • 如果发生错误,则返回一个正整数错误码。

pthread_spin_destroy(销毁自旋锁)

#include <pthread.h>

int pthread_spin_destroy(pthread_spinlock_t *lock);

lock: 指向要销毁的自旋锁对象的指针。

返回值:

  • 成功时返回 0
  • 如果发生错误,则返回一个正整数错误码。

http://www.kler.cn/a/460558.html

相关文章:

  • 【AI大模型】深入GPT-2模型细节:揭秘其卓越性能的秘密
  • Redis 发布订阅(Pub/Sub)机制详解
  • 慧集通iPaaS集成平台低代码训练-实践篇
  • 丢弃法hhhh
  • AWS S3文件存储工具类
  • 【ArcGISPro/GeoScenePro】检查并处理高程数据
  • Oracle库锁表处理
  • 在Ubuntu下通过Docker部署MySQL服务器
  • 论文分享 | PromptFuzz:用于模糊测试驱动程序生成的提示模糊测试
  • 【Docker】:Docker容器技术
  • SAP B1 认证考试习题 - 解析版(六)
  • ChatGPT-4助力学术论文提升文章逻辑、优化句式与扩充内容等应用技巧解析。附提示词案例
  • 百度贴吧的ip属地什么意思?怎么看ip属地
  • 2024年前端工程师总结
  • 提示词工程教程(零):提示词工程教程简介
  • 【基于语义地图的机器人路径覆盖】Radiant Field-Informed Coverage Planning (RFICP)高斯扩散场轨迹规划算法详解
  • 详细了解Redis分布式存储的常见方案
  • 在虚幻引擎4(UE4)中使用蓝图的详细教程
  • Ungoogled Chromium127编译指南 Linux篇 - 安装Python(四)
  • Quartus In-System Sources and Probes Editor 的使用说明
  • 视觉提示调优:一种高效的Transformer迁移学习新方法 - 仅需1%参数实现超越全量微调的性能
  • css绘制圆并绘制圆的半径
  • Docker部署-WebsiteGuide
  • 低空经济新动力:无人机航测技术的普及与应用
  • 企业赋能是什么意思-国际数字影像产业园解读
  • Java开发 PDF文件生成方案