【Linux】线程与线程安全知识总结

devtools/2024/10/11 4:39:45/

在这里插入图片描述

向外张望的人在做梦,
向内审视的人才是清醒的。
--- 荣格 ---

我最近复习了线程安全这部分知识,将不明白的问题总结出来,并通过AI进行问答帮助我进行学习巩固。本人能力有限 ,可能有些内容不准确,望各位大佬海涵!!!

线程与线程安全知识总结

  • 1 请简述线程安全概念与实现
  • 2 死锁发生的必要条件和避免措施
  • 3 请简述线程池的作用与实现原理
  • 4 简述并发编程的特性
  • 5 信号量实现与条件变量有什么区别?
  • 6 简述什么是线程同步,为什么需要同步

1 请简述线程安全概念与实现

线程安全指的是在多线程编程中,多个线程对临界资源进行争抢访问而不会造成数据二义或程序逻辑混乱的情况。当多个线程访问同一资源时,这些线程不会相互干扰,程序的行为仍然符合预期,不会出现数据不一致或错误的结果。
线程安全的实现,通过同步与互斥实现!

线程的同步和互斥是确保多线程程序正确执行的关键技术,具体互斥的实现可以通过互斥锁和信号量实现、而同步可以通过条件变量与信号量实现。

  1. 互斥锁(Mutexes):通过互斥锁可以保证同一时间只有一个线程访问共享资源,其他线程必须等待锁被释放后才能访问。
  2. 读写锁(Read-Write Locks):允许多个读操作同时进行,但写操作会独占锁,用于读多写少的场景。
  3. 条件变量(Condition Variables):允许线程在某些条件下挂起或被唤醒,常与互斥锁结合使用。
  4. 原子操作(Atomic Operations):提供原子性的数据操作,确保在多线程环境中对数据的修改是安全的。
  5. 线程局部存储(Thread-Local Storage, TLS):为每个线程提供独立的变量副本,从而避免共享。我们实现高并发内存池中有所使用!!!

2 死锁发生的必要条件和避免措施

死锁发生的四个必要条件:

  1. 互斥条件:资源不能被多个进程同时使用,只能由一个进程独占直到该进程释放资源。
  2. 占有和等待条件:进程至少持有一个资源,并且正在等待获取额外的资源,而该资源又被其他进程持有。
  3. 不可抢占条件:已经分配给进程的资源在未使用完毕之前不能被其他进程强行抢占。
  4. 循环等待条件:存在一种进程资源的循环等待链,每个进程至少持有一个资源,并等待获取下一个进程所持有的资源。

解决死锁的方法就是破坏死锁发生的必要条件,这样就可以避免死锁发生:

  1. 破坏互斥条件:
    • 尽可能使资源可共享,但这在许多情况下不可行,因为有些资源(如打印机)本质上就是互斥的。
  2. 破坏持有和等待条件:
    • 要求线程在开始执行前一次性声明所有需要的资源。
    • 如果无法一次性获取所有资源,线程可以在持有部分资源的情况下释放它们,然后重新尝试获取全部资源。
  3. 破坏非抢占条件:
    • 允许线程抢占资源,但这可能导致系统复杂度和不确定性增加。
    • 实现抢占式调度策略,可以在一定条件下强制回收资源。
  4. 破坏循环等待条件:
    • 对所有资源类型进行排序,并要求线程只能按照顺序请求资源。
    • 通过资源分级避免循环等待。

上面是方法理论,我们可以通过以下这些具体的方法来避免死锁:

  1. 资源分配策略:避免动态资源分配,而是预先分配资源。使用银行家算法来避免系统进入不安全状态。
  2. 锁的顺序:确保所有线程以相同的顺序请求和释放锁。
  3. 超时机制:如果线程在一段时间内没有获取到锁,则放弃并重新尝试。

3 请简述线程池的作用与实现原理

面试简述:

线程池通过一个线程安全的阻塞任务队列加上一个或一个以上的线程实现,线程池中的线程可以从阻塞队列中获取任务进行任务处理,当线程都处于繁忙状态时可以将任务加入阻塞队列中,等到其它的线程空闲后进行处理。
可以避免大量线程频繁创建或销毁所带来的时间成本,也可以避免在峰值压力下,系统资源耗尽的风险;并且可以统一对线程池中的线程进行管理,调度监控。

线程池项目之前的文章有详细讲过。其使用的是资源复用的思想,通过池化技术来实现:

池化技术(Pooling)是一种在计算机科学中常用的资源管理技术,其核心思想是预先分配并管理一定数量的资源,当需要使用资源时,不是每次都重新创建新的资源,而是从预先分配的资源池中取出资源进行使用,使用完毕后再归还到资源池中,以供后续重用。这种技术可以显著减少资源创建和销毁的开销,提高资源利用率,降低系统延迟。

4 简述并发编程的特性

  1. 原子性:C++中的原子操作保证了对共享数据的修改在多线程环境中是不可分割的,即其他线程看不到操作的一半状态,确保了数据的一致性。
  2. 可见性:C++通过内存模型保证,当线程对共享变量进行写操作后,其他线程能够立即看到这些修改,避免了读取到旧数据的问题。
  3. 有序性:C++的内存模型确保了程序中的操作按照特定的顺序执行,防止编译器和处理器对指令进行重排序,从而保证了多线程环境下的执行顺序与代码中的顺序一致。

5 信号量实现与条件变量有什么区别?

  • 条件变量提供了一个pcb阻塞队列以及阻塞和唤醒线程的接口用于实现同步,但是什么时候该唤醒以及什么时候该阻塞线程由程序员进行控制,而这个控制通常需要一个共享资源的条件判断完成,因此条件变量还需要搭配互斥锁使用,来保护这个共享资源的条件判断及操作。

  • 信号量提供一个pcb等待队列,以及一个实现了原子操作的对资源进行计数的计数器,通过自身计数器实现同步的条件判断,因此不需要搭配互斥锁使用,而且信号量在初始化计数为1的情况下也可以模拟实现互斥操作。

6 简述什么是线程同步,为什么需要同步

线程同步是指通过特定的机制协调多个线程的执行,使得它们能够按照一定的顺序或条件访问共享资源,避免并发执行时产生的数据竞争和状态不一致问题。

为什么需要同步:

  • 防止竞态条件:当多个线程同时访问和修改同一数据时,没有适当的同步可能导致不可预测的结果。
  • 保持数据一致性:同步机制确保共享数据的修改对其他线程可见,维护数据的正确性。
  • 控制执行顺序:在某些情况下,需要确保某些操作按照特定的顺序执行,同步可以提供这种控制。
  • 避免死锁和饥饿:合理的同步策略有助于避免线程因资源争夺而无法继续执行的情况。

http://www.ppmy.cn/devtools/123985.html

相关文章

TadTR(TIP 2022)视频动作检测方法详解

前言 论文:End-to-end Temporal Action Detection with Transformer 代码:TadTR 从论文题目可以看出 TadTR 是基于 Transformer 的端到端的方法,TAD 在视频动作分类任务上更进一步,不仅对动作分类,还要检测动作发生的…

王道408考研数据结构-图-第六章

6.1 图的基本概念 6.1.1 图的定义 图G由顶点集V和边集 E组成,记为G(V,E),其中 V(G)表示图G中顶点的有限非空集;E(G)表示图G中顶点之间的关系(边)集合。若V{v?,v?,…,vn},则用|M表示图G中顶第6章 点的个数,E{(u,v) | uεV,vεV},用|E|表示图…

vue 入门二

参考&#xff1a;丁丁的哔哩哔哩 11.组件基础 传递 props 父组件 <BlogPost title"My journey with Vue" />子组件 <script setup> defineProps([title]) </script><template><h4>{{ title }}</h4> </template>props第…

【重学 MySQL】四十九、阿里 MySQL 命名规范及 MySQL8 DDL 的原子化

【重学 MySQL】四十九、阿里 MySQL 命名规范及 MySQL8 DDL 的原子化 阿里 MySQL 命名规范MySQL8 DDL的原子化 阿里 MySQL 命名规范 【强制】表名、字段名必须使用小写字母或数字&#xff0c;禁止出现数字开头&#xff0c;禁止两个下划线中间只出现数字。数据库字段名的修改代价…

Ubuntu 22.04.4 LTS更换下载源

方法1&#xff1a;使用图形界面更换下载源 1. 打开软件和更新应用 2. 在Ubuntu 软件标签中&#xff0c;点击“下载自”旁边的下拉菜单&#xff0c;选择“其他” 3. 点击“选择最佳服务器”来自动选择最快的服务器 4. 选择服务器 5. 确定并关闭窗口&#xff0c;系统会提示您重新…

一场由Element-ui 数字输入框引发的惨案,我们应该怎么选择是否使用输入输入框?

# 本文灵感来源于工作实践 上午我接到一个功能优化的需求&#xff0c;说是如果在单位为“亩”的情况下&#xff0c;要确保他的数量不能大于地块的数量并回显&#xff0c;虽然目前已经在新增时可以实现&#xff0c;但是在修改时就直接失效了。 我当时第一时间就想到&#xff0c;…

大数据新视界 --大数据大厂之 Druid 查询性能提升:加速大数据实时分析的深度探索

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

rabbitMq------连接管理模块

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言管理的字段连接内存管理对象 前言 我们的网络通信框架使用的muduo库&#xff0c;而在mudu库中是已经有了连接的概念&#xff0c;但是我们呢还有一个信道的概念…