14内核同步(2)

合集下载

【转】多核CPU运行模式

【转】多核CPU运行模式

【转】多核CPU运⾏模式多核CPU运⾏模式主要有以下三种: •⾮对称多处理(Asymmetric multiprocessing,AMP)——每个CPU内核运⾏⼀个独⽴的操作系统或同⼀操作系统的独⽴实例(instantiation)。

•对称多处理(Symmetric multiprocessing,SMP)——⼀个操作系统的实例可以同时管理所有CPU内核,且应⽤并不绑定某⼀个内核。

•混合多处理(Bound multiprocessing,BMP)——⼀个操作系统的实例可以同时管理所有CPU内核,但每个应⽤被锁定于某个指定的核⼼。

1、⾮对称多处理(AMP) AMP给开发者提供了⼀个与传统单核系统相类似的运⾏环境,使得开发者已有的⼀系列经验和知识可以继续加以利⽤;同时,这也为⽼程序的移植提供了相当⼤的便利性。

AMP分为同构(homogeneous)和异构(heterogeneous)。

前者是指所有内核运⾏同⼀种类型和版本的,后者则是指每个内核运⾏不同类型或版本的操作系统(⽐如⼀个内核运⾏QNX Neutrino RT,⽽另⼀个内核运⾏Linux)。

在同构环境中,开发⼈员只要选择⼀个可提供分布式编程模式的操作系统,就能最⼤化地利⽤多核,允许某个内核上的应⽤程序透明地与另⼀个内核上的应⽤/系统服务(如设备、协议堆栈)进⾏,但不会有传统IPC机制所造成的⾼CPU占有率。

异构环境的要求有些不同。

在这种环境下,开发⼈员要么执⾏专有的通信协议,要么选择可供IPC共享相同架构(如基于IP)的两个操作系统。

为了避免资源冲突,两个操作系统还需要通过⼀个标准机制来访问被共享的硬件。

在AMP系统中,⼀个进程(process)总是运⾏在同⼀个内核中,即使其他内核处于空闲状态。

结果会导致⼀个内核要么没有被充分利⽤,要么被利⽤过度。

为了解决这个问题,系统会允许应⽤程序在内核间动态迁移。

然⽽,这样就需要对状系统信息进⾏相当复杂的检测。

浅谈linux性能调优之十七:进程绑定与中断绑定

浅谈linux性能调优之十七:进程绑定与中断绑定

浅谈linux性能调优之十七:进程绑定与中断绑定1.使用taskset设置CPU亲和性taskset搜索并设定运行进程的CPU亲和性(根据进程ID)。

它还可用于启动给定CPU亲和性的进程,这样就可将指定的进程与指定的CPU或者一组CPU捆绑CPU 亲和性使用位掩码表示。

最低位对应第一个逻辑 CPU,且最高位对应最后一个逻辑CPU。

这些掩码通常是十六进制,因此0x00000001 代表处理器 1,0x00000003 代表处理器 3 。

要设定运行进程的 CPU 亲和性,请执行以下命令,使用处理器或者您要捆绑到的处理器掩码替换 mask,使用您要更改亲和性的进程的进程 ID 替换 pid。

# taskset -p mask pid要启动给定亲和性的进程,请运行以下命令,使用处理器或者您要捆绑的处理器的掩码替换 mask,使用程序、选项以及您要运行的程序参数替换 program。

# taskset mask -- program与其将处理器指定为位码,您还可以使用 -c 选项提供逗号分开的独立处理器,或者一组处理器列表,类似如下:# taskset -c 0,5,7-9 -- myprogram有关 taskset 的详情请参考 man page:man taskset。

2.硬件中断发生频繁,是件很消耗 CPU 资源的事情,在多核 CPU 条件下如果有办法把大量硬件中断分配给不同的 CPU (core) 处理显然能很好的平衡性能。

现在的服务器上动不动就是多 CPU 多核、多网卡、多硬盘,如果能让网卡中断独占1个 CPU (core)、磁盘 IO 中断独占1个 CPU 的话将会大大减轻单一 CPU 的负担、提高整体处理效率。

中断请求(IRQ)是用于服务的请求,在硬件层发出。

可使用专用硬件线路或者跨硬件总线的信息数据包(消息信号中断,MSI)发出中断。

启用中断后,接收IRQ 后会提示切换到中断上下文。

内核中断调度代码会搜索 IRQ 号码机器关联的注册中断服务路由(ISR)列表,并按顺序调用 ISR。

Cortex-M0内核

Cortex-M0内核

异常掩码寄存器 PRIMASK
使用MSR、MRS或CPS指令改变寄存器的值,以关闭或使能异常 PRIMASK=1,可关闭所有优先级可配置的异常(除NMI和Hard Fault)
CONTROL寄存器
控制处理器处于线程模式是,使用哪个堆栈 =0,使用MSP =1,使用PSP 处理器模式时,固定使用 MSP
Thumb-2指令 集成可配置的NVIC 和Cortex-M3兼容
微处理器架构
带跳转预测的3级流水线 1条 AHB-Lite总线接口
可配置的超低功耗模式
深度睡眠、唤醒中断控制器
针对广泛应用的灵活配置
可配置的中断控制器(带优先级的最多32个中断) 不带内存保护单元MPU 可选的调试&跟踪功能
Cortex-M系列的软件兼容性(2)
向下路径(M3->M0)的移植需要注意
M0内核的NVIC和SCB寄存器只能字访问,M3可支持字、半字、 字节访问 M3内核的某些NVIC和SCB寄存器在M0中没有
Interrupt Active Status Register Software Trigger Interrupt Register Vector Table Offset Register 某些 fault status registers
异常模型
异常 编号 1 IRQ 编号 异常类型 Reset 优先级 -3,最高 异步 备注
2
3 4-10 11 12-13 14 15 16即 以上
-14
-13 -5 -2 -1 0即 以上
NMI
Hard Fault SVCall PendSV SysTick IRQ
-2

LTP使用说明

LTP使用说明

LTP工具说明1LTP测试套件 (3)1.1简介 (3)1.2源目录结构 (3)2LTP安装 (4)2.1下载 (4)2.2编译 (4)2.3安装说明 (5)3LTP测试套件结构说明 (6)3.1概述 (6)3.2目录介绍 (6)3.3LTP执行原理 (6)4LTP测试套件测试内容 (7)4.1LTP测试套件测试内容 (7)4.1.1commands (7)4.1.2kernel (7)4.1.3kdump (8)4.1.4network (8)4.1.5realtime (8)4.1.6open_posix_testsuite (8)4.1.7misc (8)4.2测试方法说明 (8)4.2.1commands模块内容描述及实现方法 (8)4.2.2kernel (10)4.2.3network (15)4.2.4open_posix_testsuite (17)4.2.5realtime (18)5LTP测试套件配置详细 (19)5.1networktests.sh脚本配置 (19)5.2networkstress.sh配置 (23)5.3open_posix_testsuite测试套件 (28)5.4realtime配置 (29)5.5mm脚本的配置 (30)5.6io脚本配置 (30)5.7filecaps的配置 (30)5.8tpm_tools的配置 (31)5.9tcore的配置 (31)5.10io_floppy的配置 (31)5.11io_cd 的配置 (32)5.12cpuhotplug的配置 (32)5.13adp.sh的配置 (33)5.14autofs1.sh和autofs4.sh的配置 (34)5.15exportfs.sh的配置 (34)5.16isofs.sh的配置 (34)5.17ltpdmmapper.sh的配置 (35)5.18ltpfslvm.sh的配置及要求 (36)5.19ltpfsnolvn.sh的配置及要求 (36)5.20ltp-scsi_debug.sh的配置及要求 (37)5.21sysfs.sh的配置及要求 (37)5.22rpctirpc的配置及要求 (37)5.23test_selinux.sh的配置及要求 (39)5.24smack的配置和要求 (40)5.25perfcounters的配置及要求 (41)5.26can的配置及要求 (41)5.27test_robind.sh的配置 (42)6LTP测试套件使用说明 (43)6.1概述 (43)6.2测试方法 (44)6.2.1初始测试 (44)6.2.2压力测试 (47)1LTP测试套件1.1简介LTP(Linux Test Project)是SGI、IBM、OSDL和Bull合作的项目,目的是为开源社区提供一个测试套件,用来验证Linux系统可靠性、健壮性和稳定性。

Linux_C_同步_内核原子_自旋锁_互斥锁

Linux_C_同步_内核原子_自旋锁_互斥锁

Linux 同步方法剖析内核原子,自旋锁和互斥锁你也许接触过并发(concurrency)、临界段(critical section)和锁定,不过怎么在内核中使用这些概念呢?本文讨论了 2.6 版内核中可用的锁定机制,包括原子运算符(atomic operator)、自旋锁(spinlock)、读/写锁(reader/writer lock)和内核信号量(kernel semaphore)。

本文还探讨了每种机制最适合应用到哪些地方,以构建安全高效的内核代码。

本文讨论了 Linux 内核中可用的大量同步或锁定机制。

这些机制为 2.6.23 版内核的许多可用方法提供了应用程式接口(API)。

不过在深入学习 API 之前,首先需要明白将要解决的问题。

并发和锁定当存在并发特性时,必须使用同步方法。

当在同一时间段出现两个或更多进程并且这些进程彼此交互(例如,共享相同的资源)时,就存在并发现象。

在单处理器(uniprocessor,UP)主机上可能发生并发,在这种主机中多个线程共享同一个 CPU 并且抢占(preemption)创建竞态条件。

抢占通过临时中断一个线程以执行另一个线程的方式来实现 CPU 共享。

竞态条件发生在两个或更多线程操纵一个共享数据项时,其结果取决于执行的时间。

在多处理器(MP)计算机中也存在并发,其中每个处理器中共享相同数据的线程同时执行。

注意在 MP 情况下存在真正的并行(parallelism),因为线程是同时执行的。

而在 UP 情形中,并行是通过抢占创建的。

两种模式中实现并发都较为困难。

Linux 内核在两种模式中都支持并发。

内核本身是动态的,而且有许多创建竞态条件的方法。

Linux 内核也支持多处理(multiprocessing),称为对称多处理(SMP)。

临界段概念是为解决竞态条件问题而产生的。

一个临界段是一段不允许多路访问的受保护的代码。

这段代码能操纵共享数据或共享服务(例如硬件外围设备)。

操作系统复习题 (3)

操作系统复习题 (3)
5.在纯用户级线程(ULT)设备中,所有线程管理的工作都是由应用程序负责、但内核知道他们的存在.F(内核是不知道线程的存在)
6.在分布式操作系统设计中,一对多(线程对进程)的关系特别有意思,因为它涉及线程转移的概念. T
7.一个控制多处理器共享存储架构的不利条件就是对整个系统控制的降低.T
8.在对称多处理系统(SMP)中,每个处理器进入到各自独立的内存领域.F (还获得了内存共享)
第四章线程、对称多处理器和微内核
复习题:
1.操作系统的基本单位调度,通常称为一个轻量级线程或线程.T
2. MS-DOS操作系统是一个单一进程具有多线程的例子.F
3.在一个多线程环境,进程是单位资源配置和保护的单位.T
4.线程同步的概念是一个多线程系统所必需的,因为单一进程的线程共享进程的进程控制块(PCB). F(因为他们有着相同地址空间)
c在不同进程之间的转换比在同一进程下的不同线程间转换花的时间少
d以上所有
4.线程基本状态发生变化,需要等待一个事件时称为: C
A.就绪状态
B.运行状态
C.阻塞状态
D.都不是
5.用户级线程(ULTs)和内核级线程(KLTs)相比一个弊端,是:B
A.调度请求准确
B.当一个ULT执行一个系统调用,进程中所有的线程都被阻塞
C.对称多处理技术
D.非以上所有
2.是实行单一制的多线程程序是:C
A.WIN 2000
B.Solaris
C.Java
D.All of the above
3.以下哪个是关于进程和线程的正确的关系:A
a.在现有的进程下创建线程要比建一个新进程下创建线程花的时间要少得多.
b终止一个进程要比一个线程花的时间长

内核同步机制-RCU同步机制

内核同步机制-RCU同步机制⽬录[]RCU同步机制RCU介绍RCU(Read-Copy Update)是⼀种极端的⾮对称读/写同步机制,基本点是允许读操作在没有任何锁及原⼦操作的情况下进⾏。

这意味着在更新操作进⾏的时候读操作也可能在运⾏。

读者临界代码不需要承担任何同步开销,不需要锁,不需要原⼦指令,在⼤多数平台,还不需要内存屏障指令。

因此,仅读的⼯作负载可以获取近乎理想的执⾏性能。

写者临界代码必须承担主要的同步开锁,为了适应读者的临界代码要求,写者必须延迟销毁数据结构和维护数据结构的多个版本,必须使⽤同步机制,如:加锁、提供排序的更新。

读者必须提供信号,让写者决定何时完成数据结构销毁操作是完全的,但该信号可能被延迟,允许⼀个单信号操作服务多个读者RCU临界代码。

RCU通常⽤⾮原⼦操作地增加⼀个本地计数器的⽅法发信号给写者,该⽅法开销很⼩。

⼀种特殊的垃圾回收器⽤于观察读者发给写者的信号,⼀旦所有护者已发信号表⽰可以安全销毁时,垃圾回收器才执⾏销毁操作。

垃圾回收器通常以类似于屏障计算的⽅式实现,或者在NUMA系统⽤⼀个联合树的形式实现。

RCU通过延迟写操作来提⾼同步性能。

系统中数据读取操作远多于写操作,⽽rwlock读写锁机制在SMP对称多处理器环境下随着处理机增多性能会迅速下降,RCU“读拷贝更新”机制改善了这种情况,RCU技术的核⼼是写操作分为“写”和“更新”两步,允许读操作在任何时候⽆阻碍访问,当系统有写操作时,更新动作⼀直延迟到对该数据的所有读操作完成为⽌。

RCU通过延迟写操作来提⾼同步性能。

下⾯⽤⼀个具体的例⼦具体的例⼦说明RCU是如何延迟更新的。

样例:使⽤RCU机制更新单向链表有两个线程访问⼀个单向链表,在线程1对元素B做没有锁的读时线程0将更新元素B。

见图1所⽰。

此时,线程0不能简单地修改元素B,因为这将⼲扰线程1对元素B的访问。

作为代替,线程0拷贝元素B到B’,修改B’,发出内存屏障操作,接着,元素A的next指针指到B’。

操作系统习题2(含答案)

操作系统总复习及相关习题第一章引论名词解释1操作系统操作系统是管理和控制计算机系统内各种硬件和软件资源,有效地组织多道程序运行的系统软件(或程序集合),是用户与计算机之间的接口。

2管态当执行操作系统程序时,处理机所处的状态3目态当执行普通用户程序时,处理机所处的状态。

4多道程序设计在这种设计技术下,内存中能同时存放多道程序,在管理程序的控制下交替的执行。

这些作业共享CPU和系统中的其他资源。

5并发是指两个或多个活动在同一给定的时间间隔中进行。

它是宏观上的概念。

6并行是指两个或多个活动在同一时刻同时执行的情况。

7吞吐量在一段给定的时间内,计算机所能完成的总工作量。

8分时就是对时间的共享。

在分时系统中,分时主要是指若干并发程序对CPU时间的共享。

9实时表示“及时”或“既时”。

10系统调用是用户在程序中能以“函数调用”形式调用的、由操作系统提供的子功能的集合。

每一个子功能称作一条系统调用命令。

它是操作系统对外的接口,是用户级程序取得操作系统服务的唯一途径。

11特权指令指指令系统中这样一些指令,如启动设备指令、设置时钟指令、中断屏蔽指令和清内存指令,这些指令只能由操作系统使用。

12命令解释程序其主要功能是接收用户输入的命令,然后予以解释并且执行。

13脱机I/O是指输入/输出工作不受主机直接控制,而由卫星机专门负责完成I/O,主机专门完成快速计算任务,从而二者可以并行操作。

14联机I/O是指作业的输入、调入内存及结果输出都在cpu直接控制下进行。

15资源共享是指计算机系统中的资源被多个进程所功用。

例如,多个进程同时占用内存,从而对内存共享;它们并发执行时对cpu进行共享;各个进程在执行过程中提出对文件的读写请求,从而对磁盘进行共享等等。

简答题1什么是操作系统?它的主要功能是什么?答:操作系统是控制和管理计算机系统内各种硬件和软件资源,有效地组织多道程序运行的系统软件(或程序集合),是用户与计算机之间的接口。

VxWorks内核及系统

2013年8月13日星期二 24
VxWorks实时内核-IPC
• 管道 1. 在VxWorks中,管道是一种通过虚拟的I/O设备来实现 的消息队列通信机制。 2. 使用函数pipeDevCreate()和pipeDevDelete()来生成和 删除管道,管道一经生成后,任务之间就可以使用标 准I/O操作主要是read()和write()进行通信。 3. 管道的优点在于它是一个I/O设备,与标准的VxWorks I/O一样,可以使用select机制,而有了select机制,一 个任务很方便地使用多个异步I/O设备,如任务要处理 同时从串口、管道、socket接收到的数据,就可以使 用select。
2013年8月13日星期二
5
实时操作系统概述

嵌入式实时操作系统功能:
多任务和可抢占的,任务具有优先级 支持可预测的任务同步机制 支持多任务间的通信 具备消除优先级转置的机制 存储器优化管理 OS的(中断延迟、任务切换、驱动程序时延等) 行为是可知的和可预测的,这是指在全负载的情形 下,最坏反应时间可知 7. 实时时钟服务 8. 中断管理服务 1. 2. 3. 4. 5. 6.
存储变量和参数code2012年12月17日星期一14vxworks实时内核多任务调度任务的优先级优先级可以动态调整2012年12月17日星期一15vxworks实时内核多任务调度进行临界区操作的任务将被特别保护等待临界区操作完成后解阻塞进行删除操作的任务删除或终止一个设定了删除保护的任务的任务将被阻塞2012年12月17日星期一16vxworks实时内核多任务调度资源回收必须由应用程序自己来实现任务应该在退出之前进行资源回收当父任务退出时要删除子任务2012年12月17日星期一17vxworks实时内核多任务调度?vxworks中默认的调度算法是基于优先级的抢占调度相同优先级的任务可采用时间片轮转方式2012年12月17日星期一18vxworks实时内核多任务调度2012年12月17日星期一19vxworks实时内核多任务调度tftpdtask55ftp服务器tnettask50任务级的网络功能异常处理任务完成不能在中断中执行的功能内核执行的第一个任务初始化设备启动用户任务并退出2012年12月17日星期一20vxworks实时内核ipc内核提供基本任务间通信机制

pt7600 说明


1. 启动前准备工作 .................................................................... 1
拆开打印机包装 ......................................................................................1 概述 ..........................................................................................................2 顶视图和底视图 ..........................................................................................2 键盘和液晶显示屏 ......................................................................................3 背景灯 ..........................................................................................................4 电源 ..........................................................................................................4 电源适配器 .................................................................................................. 4 电池 ..............................................................................................................5 充电电池组 .................................................................................................. 6 色带盒 ......................................................................................................8 安装色带盒 .................................................................................................. 8 开启 / 关闭打印机 .................................................................................10
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
如果指定的锁当前正在被获取,则返回非0, 否则,返回O
什么时候需要读写自旋锁?
有时,锁的使用可以明确划分为读者和写者
使用读写自旋锁的原则?
多个读者能够同时持有读锁 没有读者时只有一个写者能够持有写锁
方法:
初始化: 读锁:
写锁: 获得读锁后再次
试图获得写锁 会导致死锁:
读写自旋锁
read_lock() read_lock_irq()
有助于2.0内核到2.2内核的过渡 现在已成为内核可扩展性的一个障碍 BKL多用于保护代码而不是数据 在内核中不鼓励使用BKL 使用方法:
lock_kernel(); /* 临界区 */ unlock_kernel();
禁止抢占
问题:
由于内核时可抢占的,进程可以在任何时候停下来让另一个优先级更高的进程 运行 被抢占的进程可能处于临界区
自旋锁
警告:自旋锁不可递归
如果已经获得自旋锁,然后再次试图获得将会导致死锁
用于中断处理程序时要注意: 由线于上保首否有sp存内 ,先则一典us/iD*npn当临E核 你型is需可个_niFl前_g界的oI要能很ln变 很Noc区e用的cEd禁会方kk得 难_*法_中_l/So止试便iir:nrP庞 搞q断qgIs本图的Nasf大清状lLvaa地两接Oegv态(而楚sC&中次口e;Km,(复中断获禁()rm_禁l得止r杂断o_止clo自本k,在c,本kf旋地l)a因当;地g锁中s中此前);断断,调的,在用同获时内点得获核上锁得的到。自执底旋行是锁路不: 是处sp于sinp激i_nu_u活nnlloo状cckk态__iriq。rrqes也rteors正et(o&因mrer为_()loc如k, 此flag,s);我们并不提倡使 用sp对i指n_定lo的c锁k_解ir锁q,()然方后法让。中断恢复到加锁前的状态。
获得指定的读锁
读写自旋锁的方法
禁止本地中断并获得指定读锁
read_lock_irqsave()
存储本地中断的当前状态,禁止本地中断并获得指定读锁
read_unlock() read_unlock_irq()
释放指定的读锁 释放指定的读锁并激活本地中断
read_unlock_irqrestore() 释放指定的读锁并将本地中断恢复到指定的前状态
自旋锁与信号量的比较
使用自旋锁还是信号量?
需求
建议的加锁方法
低开销加锁
优先使用自旋锁
短期锁定
优先使用自旋锁
较长时间加锁 中断上下文中加锁
优先使用信号量 使用自旋锁
持有锁需要睡眠
使用信号量
可以认为是“初值为1的信号量”
其操作如下:
初始化:
▶DEFINE_MUTEX(mutexname); ▶mutex_init(mutex);
中断睡眠 down_trylock(struct semaphore *)
//试图获得信号量,如果不能得到则立即返回0 up(struct semaphore *)
//释放给定的信号量,如果有等待的进程则唤 醒
信号量
同一时间,只能有一个进程打开设备文件的代码,使 用信号量如下:
读写信号量 类似于自旋锁, 信号量也有读写信号量 如果没有写者,任意多个读者可以同时持有 读锁 如果在代码中能够明确区分读写,则使用读 写信号量 创建和初始化读写信号量:
解决方法:
使用自旋锁作为非抢占区的标记
内核抢占相关的函数
课堂小结
保证同步的最简单的方法, 原子操作
自旋锁, 最常用的方式,轻量级,只能有一个保持者,
忙等
信号量, 睡眠锁,适用稍少
相关的头文件:
linux/spinlock_types.h 自旋锁类型定义及初始化宏定义
linux/spinlock.h 自旋锁操作函数
内核同步
自旋锁 读-写自旋锁 信号量 读-写信号量 互斥体 完成变量 大内核锁
教学内容
教学要求
掌握自旋锁、信号量、互斥体、完成变量的使用方法。
自旋锁
原子操作只是保护对变量或位的操作。 临界区同一时间,只有一个任务的代码区域,可以跨 越多个函数。
举个例子,我们经常会碰到这种情况:
▶先得从一个数据结构中移出数据 ▶对其进行格式转换和解析 ▶最后再把它加入到另一个数据结构中
write_unlock_irqrestore() 释放指定的写锁并将本地中断恢复到指定的前状态
write_trylock() rw_lock_init() rw_is_locked()
试图获得指定的写琐t如果写锁不可用,返回非O值
初始化指定的rwlock_t 如果指定的锁当前已被持有,该函数返回非0值,否则返 回O
释放指定的锁
spin_unlock_irq()
释放指定的锁,并激活本地中断
spin_unlock_irqrestore()
释放指定的锁,并让本地中断恢复到以前状 态
spin_lock_init()
动态初始化指定的spinlock_t
spin_trylock() spin_is_locked()
试图获取指定的锁,如果未获取,则返回非0
整个执行过程必须是原子的,在数据被更新完毕前,不能 有其他代码读取这些数据。
显然,简单的原子操作对此无能为力,这就需要使用 更为复杂的同步方法——锁来提供保护。
自旋锁
自旋锁 任何时候只能有一个线程持有的锁 注意:自旋锁被一个线程持有时,其他线程不能获得这个 锁,只能忙等这个锁, 长时间占有自旋锁并不是一个明智的方法 接口定义在文件<linux/spinlock.h>中 自旋锁的使用: DEFINE_SPINLOCK(x); spin_lock (&mr_lock); //临界区 spin_unlock (&mr_lock);
▶count是信号量的初值;
信号量相关的方法
sema_init(struct semaphore *, int) //初始化动态创建的信号量为给定的值
down_interruptible(struct semaphore *) //试图获得信号量,如果不能得到则进入睡眠
down(struct semaphore *) //试图获得信号量,如果不能得到则进入不可
信号量适用于较长时间持有 持有信号量时可以睡眠
信号量
信号量操作头文件<asm/semaphore.h>; 静态地声明信号量
DEFINE_SEMAPHORE(name)
▶name是信号量的名字,初始值是1;
也可以用下面方式来声明、初始化信号量
struct semaphore sem; sema_init(&sem,count);
自旋锁
如果你能确定中断在加锁前是激活的,那就不需要在 解锁后恢复中断以前的状态了。你可以无条件地在解 锁时激活中断。 spin_lock_irq()
典型用直法接禁止中断,而不保存之前的状态
DsEpFiInN_Eu_nSPloINckLO_iCrqK()x);
spin_直loc接k_激irq活(&中m断r_lock);
上锁
▶mutex_lock(lock);
释放
▶mutex_unlock(lock);
互斥体
完成变量
类似于信号量
一个任务在等待完成变量,另一个进程在进行某种工作 另一个进程完成工作后,使用完成变量唤醒等待的进程 定义:
▶DECLARE_COMPLETION(work);
▶init_completion(struct completion *)
自旋锁
自旋锁提供了一种快速简单的锁实现方法。如果加锁 时间不长并且代码不会睡眠(比如中断处理程序),利用 自旋锁是最佳选择。如果加锁时间可能很长或者代码 在持有锁时有可能睡眠,那么最好使用信号量来完成 加锁功能。
信号量 Linux中信号量是睡眠锁
如果有一个任务试图获得一个已经被占用的信号 量时,信号量会将其推进到一个等待队列中,然后 让其睡眠。这时处理器可以去执行其他代码。 当持有信号量的进程将信号量释放后,处于等待 队列中的那个任务将被唤醒,并获得该信号量。
/ *临界区…*/
spin_unlock_irq (&mr_lock);
自旋锁相关的方法
spin_lock()
获取指定的自旋锁
spin_lock_irq()
禁止本地中断并获取指定的锁
spin_lock_irqsave()
保存本地中断的当前状态,禁止本地中断, 并获取指定的锁
spin_unlock()
等待完成条件
▶wait_for_completion(struct completion *)
通知等待的进程唤醒
complete(struct completion *) complete_all(struct completion *);
BKL: 大内核锁
大内核锁(BKL)是全局自旋锁
可以持有BKL睡眠 可递归 可在进程上下文中使用BKL 有害
静态声明读写信号量: DECLARE_RWSEM(name) ;
初始化动态创建的读写信号量: init_rwsem(struct rw_semaphore *sem);
操作函数 down_read(struct rw_semaphore
*sem)、up_read、down_write、up_write
自旋锁
在使用Linux读一写自旋锁时,最后要考虑的一点是 这种锁机制照顾读比照顾写要多一点。 当读锁被持有时,操作为了互斥访问只能等待,但 是,读者却可以继续成功地作占用锁。而自旋等待的 写者在所有读者释放锁之前是无法获得锁的。 所以,大量读者必定会使挂起的写者处于饥饿状态, 在你自己设计锁时一定要记住这一点。
相关文档
最新文档