关于Linux同步机制知识点整理

这篇具有很好参考价值的文章主要介绍了关于Linux同步机制知识点整理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在Linux系统中,同步机制是操作系统中非常重要的一部分,以下是一些基本要点:

互斥锁

互斥锁是一种「独占锁」,比如当线程 A 加锁成功后,此时互斥锁已经被线程 A 独占了,只要线程 A 没有释放手中的锁,线程 B 加锁就会失败,失败的线程B于是就会释放 CPU 让给其他线程,既然线程 B 释放掉了 CPU,自然线程 B 加锁的代码就会被阻塞

对于互斥锁加锁失败而阻塞的现象,是由操作系统内核实现的。当加锁失败时,内核会将线程置为「睡眠」状态,等到锁被释放后,内核会在合适的时机唤醒线程,当这个线程成功获取到锁后,于是就可以继续执行。如下图:

关于Linux同步机制知识点整理

互斥锁加锁失败,就会从用户态陷入内核态,内核帮我们切换线程,这简化了互斥锁使用的难度,但也存在性能开销。

那这个开销成本是什么呢?会有两次线程上下文切换的成本

  • 当线程加锁失败时,内核会把线程的状态从「运行」状态设置为「睡眠」状态,然后把 CPU 切换给其他线程运行;
  • 接着,当锁被释放时,之前「睡眠」状态的线程会变为「就绪」状态,然后内核会在合适的时间,把 CPU 切换给该线程运行。

线程的上下文切换的是什么?当两个线程是属于同一个进程,因为虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保持不动,只需要切换线程的私有数据、寄存器等不共享的数据。

上下文切换需要几十纳秒到几微秒之间,如果锁住的代码执行时间极短(常见情况),那花在两次上下文切换的时间就会远多于锁住代码的执行时长。而且,线程的私有数据已经在CPU的cache上都预热好了,这一出一进,数据可能就凉透了,之后反复的cache miss那可就真的酸爽。所以,锁住的代码执行只需要几纳秒的话,为啥不持有CPU继续自旋等待呢?

自旋锁

自旋锁是最比较简单的一种锁,一直自旋,利用 CPU 周期,直到锁可用。需要注意,在单核 CPU 上,需要抢占式的调度器(即通过时钟中断一个线程,运行其他线程)。否则,自旋锁在单 CPU 上无法使用,因为一个自旋的线程永远不会放弃 CPU。

自旋锁开销少,在多核系统下一般不会主动产生线程切换,适合异步、协程等在用户态切换请求的编程方式,但如果被锁住的代码执行时间过长,自旋的线程会长时间占用 CPU 资源,所以自旋的时间和被锁住的代码执行的时间是成「正比」的关系,我们需要清楚的知道这一点。

自旋锁与互斥锁使用层面比较相似,但实现层面上完全不同:当加锁失败时,互斥锁用「线程切换」来应对,自旋锁则用「忙等待」来应对。这里的忙等待,可以用「while」循环实现,但最好不要这么干!!CPU提供了「PAUSE」指令来实现忙等待。

关于Linux同步机制知识点整理

 

 

总结

互斥锁和自旋锁没有优略之分,工程中使用哪种锁,主要还是看使用场景(洗地操作)。

一般情况使用互斥锁。如果我们明确知道被锁住的代码的执行时间很短(这样的场景最普遍,就算不普遍也要改代码让这种场景普遍),那我们应该选择开销比较小的自旋锁,因为自旋锁加锁失败时,并不会主动产生线程切换,而是一直忙等待,直到获取到锁,那么如果被锁住的代码执行时间很短,那这个忙等待的时间相对应也很短。

不管使用的哪种锁,我们的加锁的代码范围应该尽可能的小,也就是加锁的粒度要小,这样执行速度会比较快。

  1. 什么是同步机制?同步机制是一种操作系统提供的机制,用于协调多个进程或线程之间的访问共享资源,防止出现竞态条件和死锁等问题。

  2. Linux中常用的同步机制有哪些?Linux中常用的同步机制包括互斥锁、读写锁、自旋锁、信号量、条件变量等。

  3. 读写锁和互斥锁的区别是什么?互斥锁加锁失败后,线程释放CPU,给其他线程;自旋锁加锁失败后,线程会忙等待,直到它拿到锁;读写锁和互斥锁都是用于保护共享资源的机制,但是它们的实现方式和使用场景不同。互斥锁通常用于保护临界区,在临界区中只允许一个进程或线程操作共享资源;读写锁用于保护读写共享资源,允许多个进程或线程同时读取共享资源,但是只允许一个进程或线程写入共享资源。

  4. 读写锁和互斥锁的使用场景:当被锁的代码消耗时间很小时推荐使用自旋锁,防止线程切换,因为线程切换时间会长一点。当被锁的代码消耗时间比较长时,推荐使用互斥锁。

  5. 信号量和条件变量的区别是什么?信号量和条件变量都是用于同步进程或线程的机制,但是它们的实现方式和使用场景不同。信号量通常用于限制共享资源的访问数量,多个进程或线程可以同时访问共享资源,但是访问数量受到信号量的限制;条件变量用于线程间的通信,允许线程在特定条件下等待和唤醒。

  6. 什么是死锁?死锁是指两个或多个进程或线程互相等待对方持有的资源,从而导致进程或线程无法继续执行的一种情况。死锁是多线程编程中常见的问题,需要通过合理的同步机制和设计来避免。

  7. Linux中如何防止死锁?Linux中提供了多种机制来防止死锁,包括资源的有序分配、避免持有多个锁、使用超时机制等。在编写多线程程序时,应该尽可能地避免使用复杂的锁嵌套,合理地设计同步机制,避免出现死锁。

  8. 什么是内核抢占?内核抢占是指内核在某些情况下可以抢占正在运行的进程或线程,以保证内核的响应能力和稳定性。内核抢占通常发生在中断处理程序中,当中断处理程序需要执行一些紧急的操作时,可以抢占正在运行的进程或线程,以保证中断处理程序的及时响应。

  9. Linux中如何实现内核抢占?Linux中提供了可抢占内核和完全抢占内核两种模式来实现内核抢占。可抢占内核是指在内核代码中插入一些抢占点,以允许内核在某些情况下抢占正在运行的进程或线程;完全抢占内核是指内核中所有的临界区都支持抢占,可以在任何时候抢占正在运行的进程或线程。可抢占内核和完全抢占内核都可以提高内核的响应能力和稳定性,但是完全抢占内核的开销更大一些。

  10. 什么是原子操作?原子操作是一种不可分割的操作,要么全部执行成功,要么全部执行失败,不会出现部分执行成功的情况。在多线程编程中,原子操作可以保证数据的一致性和线程安全性。Linux中提供了多种原子操作函数,如atomic_t、atomic_read、atomic_set等,可以用于实现同步机制和保证数据的一致性。

  11. Linux中如何实现进程间通信?Linux中提供了多种进程间通信的机制,包括管道、消息队列、共享内存、信号量、套接字等。这些机制可以用于不同进程之间的通信和数据交换。

  12. 什么是线程?线程是进程中的一个执行单元,可以与其他线程共享进程的资源。线程的使用可以提高程序的并发性和响应能力,但是需要注意线程安全性和同步机制的设计。

  13. Linux中如何实现线程?Linux中提供了多种线程的实现方式,包括用户级线程和内核级线程。用户级线程是指由用户空间的线程库实现的线程,可以提高程序的并发性和响应能力;内核级线程是指由内核实现的线程,可以充分利用多核处理器的性能优势。Linux中使用pthread库来实现线程,可以使用pthread_create、pthread_join、pthread_mutex_lock等函数来创建、等待和同步线程的执行。

  14. 什么是多线程编程中的竞态条件?竞态条件是指多个线程同时访问共享资源,从而导致数据的不可预测性和不一致性的一种情况。在多线程编程中,需要通过同步机制来避免竞态条件的出现。

  15. 什么是线程安全性?线程安全性是指在多线程环境下,程序能够正确地处理共享资源,不会出现数据的不一致性和竞态条件等问题。在多线程编程中,需要考虑线程安全性,使用合适的同步机制和设计,来保证程序的正确性和可靠性。文章来源地址https://www.toymoban.com/news/detail-514400.html

到了这里,关于关于Linux同步机制知识点整理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 关于“Python”的核心知识点整理大全5

    目录 2. 使用方法pop()删除元素 3. 弹出列表中任何位置处的元素 4. 根据值删除元素 3 章 列表简介 3.3 组织列表 3.3.1 使用方法 sort()对列表进行永久性排序 3.3.2 使用函数 sorted()对列表进行临时排序 3.3.3 倒着打印列表 3.3.4 确定列表的长度 3.5 小结 有时候,你要将元素从列表中删除

    2024年02月05日
    浏览(35)
  • 关于“Python”的核心知识点整理大全59

    目录 19.3.2 将数据关联到用户 1. 修改模型Topic models.py 2. 确定当前有哪些用户 3. 迁移数据库 注意 19.3.3 只允许用户访问自己的主题 views.py 19.3.4 保护用户的主题 views.py views.py 19.3.6 将新主题关联到当前用户 views.py 往期快速传送门👆(在文章最后): 感谢大家的支持!欢迎订阅

    2024年01月18日
    浏览(50)
  • 关于“Python”的核心知识点整理大全30

    目录 12.2.3 在 OS X 系统中安装 Pygame 12.2.4 在 Windows 系统中安装 Pygame 12.3 开始游戏项目 12.3.1 创建 Pygame 窗口以及响应用户输入 首先,我们创建一个空的Pygame窗口。使用Pygame编写的游戏的基本结构如下: alien_invasion.py 12.3.2 设置背景色 alien_invasion.py 12.3.3 创建设置类 settings.py al

    2024年01月20日
    浏览(51)
  • 关于“Python”的核心知识点整理大全15

    目录 ​编辑 7.3.2 删除包含特定值的所有列表元素 pets.py 7.3.3 使用用户输入来填充字典 mountain_poll.py 7.4 小结 第8章 函 数 8.1 定义函数 greeter.py 8.1.1 向函数传递信息 8.1.2 实参和形参 8.2.1 位置实参 2. 位置实参的顺序很重要 8.2.2 实参 往期快速传送门👆(在文章最后):

    2024年02月05日
    浏览(38)
  • 关于“Python”的核心知识点整理大全56

      目录 6. 链接到页面new_topic topics.html 19.1.2 添加新条目 1. 用于添加新条目的表单 forms.py 2. URL模式new_entry urls.py 3. 视图函数new_entry() views.py 4. 模板new_entry new_entry.html 5. 链接到页面new_entry topic.html 19.1.3 编辑条目 1. URL模式edit_entry urls.py 2. 视图函数edit_entry() views.py 往期快速传送门

    2024年01月24日
    浏览(41)
  • 关于“Python”的核心知识点整理大全49

      目录 16.2.10 加亮颜色主题 16.3 小结 第17 章 使用API 17.1 使用 Web API 17.1.1 Git 和 GitHub 17.1.2 使用 API 调用请求数据 17.1.3 安装 requests 17.1.4 处理 API 响应 python_repos.py 注意 17.1.5 处理响应字典 python_repos.py Pygal样式存储在模块style中,我们从这个模块中导入了样式RotateStyle(见1)。

    2024年02月02日
    浏览(30)
  • 关于“Python”的核心知识点整理大全21

    在Python 2.7中,继承语法稍有不同,ElectricCar类的定义类似于下面这样: 函数super()需要两个实参:子类名和对象self。为帮助Python将父类和子类关联起来,这些 实参必不可少。另外,在Python 2.7中使用继承时,务必在定义父类时在括号内指定object。 9.3.3 给子类定义属性和方法

    2024年01月16日
    浏览(39)
  • 关于“Python”的核心知识点整理大全13

    目录 6.4.3 在字典中存储字典 6.5 小结 第7章 用户输入和while循环 7.1 函数 input()的工作原理 7.1.1 编写清晰的程序 7.1.2 使用 int()来获取数值输入 7.1.3 求模运算符 7.1.4 在 Python 2.7 中获取输入 7.2 while 循环简介 7.2.1 使用 while 循环 往期快速传送门👆(在文章最后): 6.4.3 在字典中

    2024年02月04日
    浏览(46)
  • 关于“Python”的核心知识点整理大全8

    目录 ​编辑 4.5 元组 4.5.1 定义元组 dimensions.py 4.5.2 遍历元组中的所有值 4.5.3 修改元组变量 4.6 设置代码格式 4.6.1 格式设置指南 4.6.2 缩进 4.6.3 行长 4.6.4 空行 4.6.5 其他格式设置指南 4.7 小结 第5章 if语句 5.1 一个简单示例 cars.py 5.2 条件测试 5.2.1 检查是否相等 5.2.2 检查是否相等

    2024年02月05日
    浏览(40)
  • 关于“Python”的核心知识点整理大全18

    目录 ​编辑 8.5 传递任意数量的实参 pizza.py 8.5.1 结合使用位置实参和任意数量实参 8.5.2 使用任意数量的实参 user_profile.py 8.6 将函数存储在模块中 8.6.1 导入整个模块 pizza.py making_pizzas.py 8.6.2 导入特定的函数 8.6.3 使用 as 给函数指定别名 关于“Python”的核心知识点整理大

    2024年02月04日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包