Linux内核的同步机制(1)

yanqin | 2009-04-16 14:51:09    阅读:791

发布文章

一、 引言

%A

%A 在现代操作系统里,同一时间可能有多个内核执行流在执行,因此内核其实象多进程多线程编程一样也需要一些同步机制来同步各执行单元对共享数据的访问。尤其是在多处理器系统上,更需要一些同步机制来同步不同处理器上的执行单元对共享的数据的访问。在主流的Linux内核中包含了几乎所有现代的操作系统具有的同步机制,这些同步机制包括:原子操作、信号量(semaphore)、读写信号量(rw_semaphore)、spinlock、BKL(Big Kernel Lock)、rwlock、brlock(只包含在2.4内核中)、RCU(只包含在2.6内核中)和seqlock(只包含在2.6内核中)。

%A

%A

%A

%A 二、原子操作

%A

%A 所谓原子操作,就是该操作绝不会在执行完毕前被任何其他任务或事件打断,也就说,它的最小的执行单位,不可能有比它更小的执行单位,因此这里的原子实际是使用了物理学里的物质微粒的概念。

%A

%A 原子操作需要硬件的支持,因此是架构相关的,其API和原子类型的定义都定义在内核源码树的include/asm/atomic.h文件中,它们都使用汇编语言实现,因为C语言并不能实现这样的操作。

%A

%A 原子操作主要用于实现资源计数,很多引用计数(refcnt)就是通过原子操作实现的.

%A

%A

%A

%A 三、信号量(semaphore)

%A

%A Linux内核的信号量在概念和原理上与用户态的System V的IPC机制信号量是一样的,但是它绝不可能在内核之外使用,因此它与System V的IPC机制信号量毫不相干。

%A

%A 信号量在创建时需要设置一个初始值,表示同时可以有几个任务可以访问该信号量保护的共享资源,初始值为1就变成互斥锁(Mutex),即同时只能有一个任务可以访问信号量保护的共享资源。一个任务要想访问共享资源,首先必须得到信号量,获取信号量的操作将把信号量的值减1,若当前信号量的值为负数,表明无法获得信号量,该任务必须挂起在该信号量的等待队列等待该信号量可用;若当前信号量的值为非负数,表示可以获得信号量,因而可以立刻访问被该信号量保护的共享资源。当任务访问完被信号量保护的共享资源后,必须释放信号量,释放信号量通过把信号量的值加1实现,如果信号量的值为非正数,表明有任务等待当前信号量,因此它也唤醒所有等待该信号量的任务。

%A

%A

%A

%A 四、读写信号量(rw_semaphore)

%A

%A 读写信号量对访问者进行了细分,或者为读者,或者为写者,读者在保持读写信号量期间只能对该读写信号量保护的共享资源进行读访问,如果一个任务除了需要读,可能还需要写,那么它必须被归类为写者,它在对共享资源访问之前必须先获得写者身份,写者在发现自己不需要写访问的情况下可以降级为读者。读写信号量同时拥有的读者数不受限制,也就说可以有任意多个读者同时拥有一个读写信号量。如果一个读写信号量当前没有被写者拥有并且也没有写者等待读者释放信号量,那么任何读者都可以成功获得该读写信号量;否则,读者必须被挂起直到写者释放该信号量。如果一个读写信号量当前没有被读者或写者拥有并且也没有写者等待该信号量,那么一个写者可以成功获得该读写信号量,否则写者将被挂起,直到没有任何访问者。因此,写者是排他性的,独占性的。

%A

%A 读写信号量有两种实现,一种是通用的,不依赖于硬件架构,因此,增加新的架构不需要重新实现它,但缺点是性能低,获得和释放读写信号量的开销大;另一种是架构相关的,因此性能高,获取和释放读写信号量的开销小,但增加新的架构需要重新实现。在内核配置时,可以通过选项去控制使用哪一种实现。

%A

%A

%A

%A 五、自旋锁(spinlock)

%A

%A 自旋锁与互斥锁有点类似,只是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。由于自旋锁使用者一般保持锁时间非常短,因此选择自旋而不是睡眠是非常必要的,自旋锁的效率远高于互斥锁。

%A

%A 信号量和读写信号量适合于保持时间较长的情况,它们会导致调用者睡眠,因此只能在进程上下文使用(_trylock的变种能够在中断上下文使用),而自旋锁适合于保持时间非常短的情况,它可以在任何上下文使用。如果被保护的共享资源只在进程上下文访问,使用信号量保护该共享资源非常合适,如果对共巷资源的访问时间非常短,自旋锁也可以。但是如果被保护的共享资源需要在中断上下文访问(包括底半部即中断处理句柄和顶半部即软中断),就必须使用自旋锁。

%A

%A 自旋锁保持期间是抢占失效的,而信号量和读写信号量保持期间是可以被抢占的。自旋锁只有在内核可抢占或SMP的情况下才真正需要,在单CPU且不可抢占的内核下,自旋锁的所有操作都是空操作。

%A

%A 跟互斥锁一样,一个执行单元要想访问被自旋锁保护的共享资源,必须先得到锁,在访问完共享资源后,必须释放锁。如果在获取自旋锁时,没有任何执行单元保持该锁,那么将立即得到锁;如果在获取自旋锁时锁已经有保持者,那么获取锁操作将自旋在那里,直到该自旋锁的保持者释放了锁。

%A

%A 无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。

%A

%A%A%A

%A

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论

请登录...

登录后参与讨论

哪些是Linux内核的同步机制,Linux内核的同步机制(1)相关推荐

  1. Linux 内核同步(七):RCU机制

    简介 RCU 的全称是(Read-Copy-Update),意在读写-复制-更新,在 Linux 提供的所有内核互斥的设施当中属于一种免锁机制.在之前讨论过的读写自旋锁(rwlock).顺序锁(seq ...

  2. Linux内核概念:per-CPU,cpumask,inicall机制,通知链

    Linux内核概念 per-CPU,cpumask,inicall机制,通知链 rtoax 2021年3月 在英文原文基础上,针对中文译文增加5.10.13内核源码相关内容. 1. Per-cpu 变 ...

  3. linux kernel and user space通信机制,Linux内核与用户空间通信机制研究.pdf

    ISSN 1009-3044 E-mail:info@CCCC.net.CR ComputerKnowledgeandTechnology电脑知识与技术 http://www.dnzs.net.cn ...

  4. linux内核与用户空间的九种通信机制

    目前Linux提供了9种机制完成内核与用户空间的数据交换,分别是内核启动参数.模块参数与 sysfs.sysctl.系统调用.netlink.procfs.seq_file.debugfs和relay ...

  5. linux kernel and user space通信机制,Linux内核空间与用户空间通信机制地研究.doc

    实用文案 标准文档 Linux内核空间与用户空间通信机制的研究 Linux kernel space and user space communication mechanism 摘 要 Linux ...

  6. linux内核的配置过程,linux内核的配置机制及其编译过程

    linux内核的配置机制及其编译过程. 一.配置系统的基本结构 Linux内核的配置系统由三个部分组成,分别是: 1.Makefile:分布在 Linux 内核源代码根目录及各层目录中,定义 Linu ...

  7. linux驱动基础开发3——linux 内核配置机制(make menuconfig、Kconfig、makefile)讲解-转

    前面我们介绍模块编程的时候介绍了驱动进入内核有两种方式:模块和直接编译进内核,并介绍了模块的一种编译方式--在一个独立的文件夹通过makefile配合内核源码路径完成 那么如何将驱动直接编译进内核呢? ...

  8. linux收发包内核进程名称,Linux内核IP Queue机制的分析(一)——用户态接收数据包...

    序 笔者将会通过包括本文在内的三篇文章,对IP Queue机制从用户态的应用到内核态的模块程序设计进行分析.三篇文章的题目分别是: Linux内核IP Queue机制的分析(一)­--用户态接收数据包 ...

  9. linux系统如何选择内核启动,Linux系统的快速启动机制(内核切换)

    快速启动机制:允许通过已经运行的Linux内核的上下文启动另一个Linux内核,不需要经过BIOS.BIOS可能会消耗很多时间,特别是带有众多数量的外设的大型服务器.这种办法可以为经常启动机器的开发者 ...

  10. Linux内核态之间进程通信,内核态和用户态通信(二)--实现

    本文主要使用netlink套接字实现中断环境与用户态进程通信. 系统环境:基于linux 2.6.32.27 和 linux 3.16.36 Linux内核态和用户态进程通信方法的提出和实现 用户上下 ...

最新文章

  1. vue 实现 web端滚动刷新 自定义指令
  2. http协议网络编程
  3. Spring如何处理线程并发
  4. python图片找字_如何用python查找图像中的字母
  5. python读取oracle数据到hvie parquet_关于sparksql操作hive,读取本地csv文件并以parquet的形式装入hive中...
  6. 【杭电多校2020】Total Eclipse【贪心】【并查集】
  7. Django 的简单ajax
  8. SwiftUI 打开高德地图
  9. UVA 10803 - Thunder Mountain
  10. 用友T6打开UFO报表提示登录失败
  11. LeetCode 常用方法
  12. Java中常见的异常有哪些?
  13. msys2+mingw64+ragel安装
  14. 如何自己制作身份证扫描件?
  15. 徐思201771010132《面向对象程序设计(java)》第八周学习总结
  16. 怎么看别人的qq空间怎么看加密的qq空间
  17. 1730: 珠心算测验
  18. 微软研发中心招聘的背后
  19. C盘清理-我的C盘莫名其妙就满了?
  20. 与君共品代码: Spelling Corrector

热门文章

  1. CentOS 7 定时计划任务设置
  2. 日志模块-logging模块
  3. hibernate框架学习之使用SQLQuery查询数据
  4. javascript语法速查表
  5. iOS:面向对象的思想使用sqlite数据库
  6. Android开发之Java集合类性能分析
  7. 开启log4net内部调试
  8. AdoHelper使用MySQL存储过程示例
  9. C++学习——string
  10. Nginx启动后无法访问页面