linux内核调度与spinlock的相互关系
linux cpu调度机制
linux cpu调度机制
Linux操作系统的CPU调度机制主要包括以下几种:
1. 抢占式调度(Preemptive Scheduling):Linux使用抢占式调度机制,即一个进程可以被强行从CPU中移除,让另一个具有更高优先级
的进程获取执行权限。这种机制确保了高优先级进程能够及时响应,
提高系统的响应性能。
2. 时间片轮转调度(Round-Robin Scheduling):Linux使用时间片轮转调度算法,每个进程被分配一个时间片来执行,在时间片用
完后,进程被移到就绪队列的末尾,然后等待下一次调度。这种机制
保证了每个进程都有机会在CPU上运行。不过,Linux提供了动态调整时间片大小的策略,以适应不同类型的应用程序。
3. 实时调度(Real-Time Scheduling):Linux提供了实时调度策略,用于对实时任务的调度。实时任务通常具有严格的时间要求,
需要在特定的时间内完成。Linux提供了多种实时调度策略,如先进先出调度(FIFO)、最早截止时间优先调度(Earliest Deadline First,EDF)等。
4. CFS调度(Completely Fair Scheduler):CFS调度器是
Linux核心中默认的调度器。它使用一种称为红黑树的数据结构来维护就绪队列。CFS调度器以公平性为目标,尽量保证每个进程在单位时间内获得相等的CPU时间。通过动态调整进程的虚拟运行时间,CFS调度器可以根据进程的优先级调整时间片的分配。
Linux的CPU调度机制既关注实时性,也关注公平性,以提高系
linux schedutil策略
linux schedutil策略
Linux的schedutil调度策略是在Linux内核中的一种动态调度算法,它旨在根据系统负载和功耗需求实时调整CPU的频率和性能。
schedutil是Linux内核4.15版本引入的调度策略之一,由于其
在系统性能和功耗方面的优化,从而逐渐得到了广泛应用。
schedutil的设计目标是充分利用CPU的性能,同时在功耗方面做出适当的权衡,以实现更高效的资源利用。它通过动态调整CPU频率
和性能水平来实现这一目标。
schedutil主要有两个组件组成:频率调整和性能调整。频率调整是在CPU的逻辑单元之间切换电压和频率,以实现不同负载下的性能
和功耗之间的平衡。性能调整是指根据工作负载需求及时调整CPU的
性能水平。
schedutil的频率调整是通过对CPU调度器进行动态优化来实现的。调度器会根据系统负载情况调整CPU的频率,从而实现最佳性能和功
耗的平衡。当系统负载较高时,调度器会增加CPU的频率以提供更高
的性能;当系统负载较低时,调度器会调整CPU的频率以降低功耗。
schedutil的性能调整是对CPU的性能水平进行控制。它通过实时监测工作负载的需求来调整CPU的性能水平。当系统负载较高时,schedutil会提高CPU的性能水平以满足需求;当系统负载较低时,schedutil会降低CPU的性能水平以节省功耗。
schedutil的优势在于它能够根据系统负载和功耗需求来动态调整CPU的频率和性能,从而实现更高效的资源利用。它可以在不降低系统响应性能的情况下节省能源,提高系统的整体性能。
linux内核锁(不允许抢占)
linux内核锁(不允许抢占)
进程调度
调度的发⽣有两种⽅式
1、主动式
在内核中直接调⽤schedule()。当进程需要等待资源等⽽暂时停⽌运⾏时,会把状态置于挂起(睡眠),并主动请求调度,让出CPU。主动放弃cpu例:
1. current->state = TASK_INTERRUPTIBLE;
2. schedule();
2、被动式(抢占)
被动式⼜分两种情况
1. ⽤户抢占(Linux
2.4、Linux2.6)
2. 内核抢占(Linux2.6)
⽤户抢占发⽣在:
从系统调⽤返回⽤户空间。
从中断处理程序返回⽤户空间。
内核即将返回⽤户空间的时候,如果need_resched标志被设置,会导致schedule()被调⽤,此时就会发⽣⽤户抢占.
* ENTRY(ret_from_exception) //异常返回
get_thread_info tsk
mov why, #0
b ret_to_user
* __irq_usr: //在⽤户态收到中断
usr_entry
kuser_cmpxchg_check
…… …… ……
b ret_to_user
ENTRY(ret_to_user)
ret_slow_syscall:
disable_irq @ disable interrupts
ldrr1, [tsk, #TI_FLAGS]
tstr1, #_TIF_WORK_MASK
bne work_pending
work_pending:
tstr1, #_TIF_NEED_RESCHED
bne work_resched
linux softlockup 原理
linux softlockup 原理
Linux softlockup是指内核中的一个线程在超过定时器时间限
制时仍未恢复,在这种情况下内核会将其视为软锁定(softlockup)。
原理如下:
1. Softlockup监控定时器(softlockup_tasklet)定期启动,其默认间隔为10秒。
2. 当定时器触发时,内核会扫描所有活动进程的状态。如果某个进程在超过10秒的时间内未能执行任何可调度任务,内核
会记录该进程线程的转储信息。
3. 内核会针对软锁定的线程发送警告信息到系统日志(dmesg)中,以及触发软中断。这个软中断(NMI软中断)会让处理
器停止并报告软锁定消息。
4. 软锁定转储信息通常包含被锁定线程的调用栈、寄存器的值、以及其他相关信息,用于分析软锁定的原因。
软锁定通常是发生在内核中的某个代码路径上,导致一个线程在操作系统内核中长时间阻塞。软锁定通常是由于内核资源争用、死循环、竞争条件或内核错误等原因引起的。
通过监控和记录软锁定事件,可以帮助开发人员识别和调试系统中的性能问题。但需要注意的是,软锁定并不一定意味着系
统上存在严重的问题,可能只是应用程序或硬件的正常行为模式。因此,软锁定事件的分析需要结合系统上下文和其他日志信息进行综合评估。
嵌入式linux的实时分析与改进
嵌入式linux的实时分析与改进
摘要嵌入式linux在工业控制领应用越来越广泛。但是,在针对一些有较强实时性要求的特定工业应用中,仍然暴露出了技术缺陷。本文针对目前linux实时系统调度算法中仅用进程的价值来确定优先级的思路,提出了综合考虑进程的价值和紧迫度来决定优先级的调度算法。
关键词嵌入式;linux实时性;调度;算法;优先级
中图分类号 tb文献标识码 a 文章编号
1674-6708(2010)17-0096-02
0 引言
嵌入式linux系统是标准linux在嵌入式领域的延伸,其特点和功能与标准linux几乎完全相同。linux系统的稳定性和健壮性已经在真实世界中得到了证明,在工业控制领域也有许多非常成功的应用。但是由于linux不是真正的实时操作系统,成为工业控制应用中的瓶颈。
1 标准linux内核制约实时性的因素
1.1 内核不可抢占
linux 2.6内核并不是真正的rtos,仅是在内核代码中插入抢占点,从而实现一定程度上的抢占,但是并不是所有的内核代码段都可以通过插入抢占点来实现抢占。
1.2 自旋锁(spinlock)
自旋锁是在可抢占内核和smp情况下对共享资源的一种同步机
制。在linux 2.6内核中,自旋锁的使用非常普遍。因此造成了抢占延迟,这对实时性要求高的工业控制来说是致命的。
1.3 系统调度算法
在linux 2.6内核中引入的o(1)调度算法,该算法很好地解决了linux 2.4以前的版本中smp性能瓶颈问题。但是该算法主要着眼点在进程的价值,而没有考虑进程的紧迫性。从而导致部分价值相当,而紧迫性高的进程过早的夭折。
Linux内核同步机制简介分析
Linux内核同步机制简介
1 介绍
1)由于现代Linux操作系统是多任务、SMP、抢占式以及中断是异步执行的,导致共享资
源容易被并发访问,从而使得访问共享资源的各线程之间互相覆盖共享数据,造成被访问数据处于不一致状态,因此Linux提供了同步机制来防止并发访问。
2)常用的同步机制(如自旋锁)用来保护共享数据使用起来简单有效,但由于CPU的
处理速度与访问内存的速度差距越来越大,导致获取锁的开销相对于CPU的速度在不断的增加。因为这种锁使用了原子操作指令,需要原子地访问内存,即获取锁的开销与访问内存的速度相关。
3)Linux内核根据对不同共享资源的特性,提供多种同步机制:原子操作、自旋锁、读-
写自旋锁、信号量、读-写信号量、完成变量、顺序锁、禁止抢占、内存屏障及RCU,本文将对其分别进行简要介绍。
2 原子操作(atomic)
2.1 基本原理
1)所谓原子操作,就是该操作绝不会在执行完毕前被任何其它任务或事件打断,它是
最小的执行单位,不可能有比它更小的执行单位。
2)原子操作通常是内联函数,通过内联汇编指令来实现。
3)原子操作需要硬件的支持,因此不同的体系结构的实现方式不同。
4)内核提供了两组原子操作接口:整数操作和位操作。
2.1.2 原子整数操作
1)原子操作主要用于实现资源计数,很多引用计数就是通过原子操作实现的。
2)原子类型定义如下:(参看RHEL6.5GA_x86_64内核文件:/root/include/linux/types.h)
3)针对整数的原子操作只能对atomic_t类型的数据进行处理,原因如下:
linux磁盘调度策略
linux磁盘调度策略
Linux磁盘调度策略
磁盘调度策略是操作系统中的一个重要组成部分,它决定了磁盘上的数据访问顺序。Linux操作系统提供了多种磁盘调度策略,以满足不同场景下的需求。本文将介绍Linux中常见的磁盘调度策略,包括CFQ、Deadline和NOOP。
1. CFQ磁盘调度策略
CFQ(Completely Fair Queuing)是Linux内核默认的磁盘调度策略。它采用了时间片轮转的方式,为每个进程提供公平的磁盘访问机会。CFQ会将磁盘请求按照优先级进行分类,并为每个进程分配一定数量的时间片进行磁盘访问。优先级高的进程会获得更多的时间片,从而获得更快的磁盘响应速度。CFQ适用于大多数常规应用场景,能够保证公平性和稳定性。
2. Deadline磁盘调度策略
Deadline磁盘调度策略以最小化磁盘请求的响应时间为目标。它将磁盘请求分为两类:实时请求和普通请求。实时请求具有更高的优先级,需要在规定时间内完成。而普通请求则在规定时间内按照先进先出的原则进行处理。Deadline通过维护两个队列,分别处理实时请求和普通请求,以保证实时请求的响应时间。
3. NOOP磁盘调度策略
NOOP磁盘调度策略是一种简单的FIFO(先进先出)调度策略。它不对磁盘请求进行排序,直接按照请求的先后顺序进行处理。NOOP适用于低负载的系统,可以减少磁盘调度的开销,提高系统的响应速度。
4. 其他磁盘调度策略
除了CFQ、Deadline和NOOP,Linux还提供了其他一些磁盘调度策略,如Anticipatory、AS(Anticipatory Scheduler)和BFQ (Budget Fair Queuing)等。这些策略在特定场景下有着不同的表现和优势。例如,Anticipatory策略在读取大文件时表现较好,而AS策略则适用于多媒体和数据库等需要低延迟的应用。
Linux中的常见锁及其基本原理
Linux中的常见锁及其基本原理
0.概述
通过本⽂将了解到如下内容:
Linux系统的并⾏性特征
互斥和同步机制
Linux中常⽤锁的基本特性
互斥锁和条件变量
1.Linux的并⾏性特征
Linux作为典型的多⽤户、多任务、抢占式内核调度的操作系统,为了提⾼并⾏处理能⼒,⽆论在内核层⾯还是在⽤户层⾯都需要特殊的机制来确保任务的正确性和系统的稳定运⾏,就如同⼀个国家需要各种法律条款来约束每个公民的⾏为,才能有条不紊地运转。
在内核层⾯涉及到各种软硬件中断、进线程睡眠、抢占式内核调度、多处理器SMP架构等,因此内核在完成⾃⼰⼯作的时候⼀直在处理这些资源抢占的冲突问题。
在⽤户层⾯的进程,虽然Linux作为虚地址模式操作系统,为每个进程开辟了独⽴的虚拟地址空间,伪独占式拥有资源,但是仍然存在很多场景不得不产⽣多个进程共享资源的问题,来完成进程间的通信,但是在Go语⾔中进程间的通信使⽤消息来完成,处理地更优雅⼀些。
在线程层⾯,线程作为进程的⼀部分,进程内的多个线程只拥有⾃⼰的独⽴堆栈等少量结构,⼤部分的资源还是过线程共享,因此多线程的资源占⽤冲突⽐进程更加明显,所以多线程编程的线程安全问题是个重难点。
综上可知,⽆论在kernel还是user space都必须有⼀些机制来确保对于资源共享问题的解决,然后这个机制就是接下来要说的:同步和互斥。
2.同步和互斥机制
基本概念
同步和互斥的概念有时候很容易混淆,可以简单地认为同步是更加宏观⾓度的⼀种说法,互斥是冲突解决的细节⽅法。
所谓同步就是调度者让任务按照约定的合理的顺序进⾏,但是当任务之间出现资源竞争,也就是竞态冲突时,使⽤互斥的规则强制约束允许数量的任务占⽤资源,从⽽解决各个竞争状态,实现任务的合理运⾏。
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内核分析之调度算法
linux调度算法在2.6.32中采用调度类实现模块式的调度方式。这样,能够很好的加入新的调度算法。
linux调度器是以模块方式提供的,这样做的目的是允许不同类型的进程可以有针对性地选择调度算法。这种模块化结构被称为调度器类,他允许多种不同哦可动态添加的调度算法并存,调度属于自己范畴的进程。每个调度器都有一个优先级,调度代码会按照优先级遍历调度类,拥有一个可执行进程的最高优先级的调度器类胜出,去选择下面要执行的那个程序。
linux上主要有两大类调度算法,CFS(完全公平调度算法)和实时调度算法。宏
SCHED_NOMAL主要用于CFS调度,而SCHED_FIFO和SCHED_RR主要用于实时调度。如下面的宏定义:
1. /*
2. * Scheduling policies
3. */
4. /*支援Real-Time Task的排程,包括有SCHED_FIFO與SCHED_RR.
5. */
6.
7. /*(也稱為SCHED_OTHER): 主要用以排程
8. 一般目的的Task.*/
9. #define SCHED_NORMAL 0
10. #define SCHED_FIFO 1
11. /*task預設的 Time Slice長度為100 msecs*/
12. #define SCHED_RR 2
13. /*主要用以讓Task可以延長執行的時間
14. (Time Slice),減少被中斷發生Task Context-Switch
15. 的次數.藉此可以提高 Cache的利用率
per_cpu机制
per_cpu机制
在Linux内核中,per_cpu机制通过宏和函数来实现。它允许
内核开发人员将数据结构标记为“per_cpu”,这意味着每个处理器
都有自己的副本。这样一来,在处理器之间不需要进行同步操作,
从而避免了锁竞争和性能下降。
per_cpu机制在许多方面都有用处。例如,在多处理器系统中,内核需要跟踪每个处理器的运行时间、负载情况等信息,per_cpu
机制可以让内核为每个处理器维护这些信息的副本,从而避免了对
全局数据结构的频繁访问和更新。此外,per_cpu机制还可以用于
分配中断处理程序、内存管理和调度等方面,以提高系统的并发性能。
总的来说,per_cpu机制是一种在多处理器系统中管理资源的
有效方式,它通过为每个处理器分配独立的资源来提高系统的性能
和可伸缩性。在Linux内核中,per_cpu机制被广泛应用于各个子
系统中,以提高系统的并发处理能力。
linux内核锁实现原理
linux内核锁实现原理
Linux内核锁是Linux操作系统中实现多线程同步和互斥的一种机制。在并发编程中,多个线程同时访问共享资源时,为了避免出现数据竞争和不一致的情况,需要使用锁来保护共享资源的访问。
Linux内核提供了多种类型的锁,例如互斥锁(mutex)、读写锁(rwlock)、自旋锁(spinlock)等。不同类型的锁适用于不同的场景和需求。下面将详细介绍Linux内核锁的实现原理。
1. 互斥锁(Mutex):
互斥锁是最常用的一种锁,用于实现对临界区的互斥访问。Linux 内核中的互斥锁实现主要依赖于原子操作和等待队列。原子操作用于实现锁的获取和释放操作,保证了这些操作的原子性,避免了竞态条件。等待队列用于管理等待锁的线程,当一个线程尝试获取锁失败时,会被放入等待队列中,直到锁被释放后再唤醒等待队列中的线程。
2. 读写锁(RWLock):
读写锁是一种特殊的锁,用于实现对共享资源的读写操作。它允许多个线程同时读取共享资源,但在写操作时必须互斥。Linux内核中的读写锁实现主要依赖于原子操作和等待队列。读操作不需要加锁,只有写操作需要加锁。读写锁内部维护了两个计数器,一个用于记录读操作的数量,一个用于记录写操作的数量。读操作时,会
增加读计数器;写操作时,会判断读计数器和写计数器是否为零,如果不为零则等待;如果为零则增加写计数器。当读操作和写操作完成后,会相应地减少计数器。
3. 自旋锁(Spinlock):
自旋锁是一种特殊的锁,用于实现对临界区的互斥访问。与互斥锁不同的是,自旋锁不会主动释放CPU资源,而是一直尝试获取锁,直到获取成功。自旋锁的实现主要依赖于原子操作。当一个线程尝试获取自旋锁失败时,会不断地尝试获取锁,直到获取成功。这种方式适用于临界区的持有时间很短的情况,避免了线程切换的开销。
计算机操作系统(第二版)课件:Linux 进程调度算法解析
虚拟运行时间:vruntime ➢ 将进程nice值转换为权重weight
3.5.3 Linux/openEuler 进程调度算法解析
完全公平调度器:CFS 虚拟运行时间:vruntime ➢ CPU运行期period:就绪队列中所有任务运行完一遍的时间
CFS调度器的相关数据结构
➢ 进程描述符task_struck结构:
struct task_struct { volatile long state; /* 进程状态*/ int prio, static_prio, normal_prio; /* 进程优先级*/ unsigned int rt_priority; /* 实时进程的实时优先级*/ const struct sched_class *sched_class; /* 进程的调度器类*/ struct sched_entity se; /* 普通进程调度实体*/ struct sched_rt_entity rt; /* 实时进程调度实体*/ ......
T(mB s) V(mTsB)
说明 (每次period中,A可运行2.4ms,B可运行17.6ms)
10
10
683
0
0
20
10
683
10
关键代码段(CriticalSections)和自旋锁(Spinlocks)
关键代码段(CriticalSections)和⾃旋锁(Spinlocks)
写在前⾯:今天⼀哥们问我,windows的临界代码是⾃旋还是等待,当时想了想应该是等待,后来翻了⼀下《Windows via C/C++》,发现还有点⼩意思。总结⼀下先。
关键代码段是指⼀个⼩代码段,在代码能够执⾏前,它必须独占对某些共享资源的访问权。这是让若⼲⾏代码能够“以原⼦操作⽅式”来使⽤资源的⼀种⽅法。所谓原⼦操作⽅式,是指该代码知道没有别的线程要访问该资源。当然,系统仍然能够抑制你的线程的运⾏,⽽抢先安排其他线程的运⾏。不过,在线程退出关键代码段之前,系统将不给想要访问相同资源的其他任何线程进⾏调度。
来看⼀段使⽤关键代码段的程序:
const int COUNT = 10;
int g_nSum = 0;
CRITICAL_SECTION g_cs;
DWORD WINAPI FirstThread(PVOID pvParam) {
EnterCriticalSection(&g_cs);
g_nSum = 0;
for (int n = 1; n <= COUNT; n++) {
g_nSum += n;
}
LeaveCriticalSection(&g_cs);
return(g_nSum);
}
DWORD WINAPI SecondThread(PVOID pvParam) {
EnterCriticalSection(&g_cs);
g_nSum = 0;
for (int n = 1; n <= COUNT; n++) {
Linux的Spinlock在MIPS多核处理器中的设计与实现
Linux的Spinlock在MIPS多核处理器中的设计与实现
引⾔
随着科技的发展,尤其是在嵌⼊式领域,⾼性能、低功耗的处理器成为众多⼚商追逐的⽬标,但是由于技术和⼯艺的瓶颈,试图在单核处理器上达到这样的⽬标变得越发困难,于是⼈们提出了多核处理器的概念。多核处理器的核⼼思想是⼀个处理器中包含若⼲个核(或线程),所有核(或线程)之间共享 IO、Cache、内存等资源,对于这些资源的使⽤和分配由硬件来完成,⽤户⽆需关注细节,因此每个核(或线程)对于⽤户来说就好像⼀个独⽴的虚拟 CPU,从⽤户⾓度来看,这个虚拟 CPU 独占所有的外设资源。
⽬前⽐较流⾏的多核处理器的架构有下⾯⼏种:
(1)SMP(Symmetric Multi-Processor)
这种架构的处理器由多个核组成,每个核有⾃⼰独⽴的 Cache,所有核共享内存和 IO。
(2)SMT(Symmetric Multi-Thread)
这种架构的处理器的每个核由多个线程组成(此处的线程指的硬件线程,⽽不是我们所说的操作系统的线程概念),每个核下的所有线程共享寄存器、ALU(CPU 运算单元)、Cache、内存、IO 等资源,线程之于⽤户也像⼀个虚拟的 CPU。这种架构的最⼤优势在于线程和线程之间的切换很快,通常⼀个时钟周期内就能完成。
(3)NUMA(Non-Uniform Memory Access)
这种架构和前⾯两种的区别在于它不是简单的⼀个处理器,⽽是⼀个由多个处理器组成的系统,每个处理器作为⼀个结点在该系统中存在。对于内存、IO 等资源所有结点也是共享的。
LINUX内核的几种锁介绍
LINUX内核的几种锁介绍
以下是LINUX内核中几种常见的锁的介绍:
1. 自旋锁(spinlock):自旋锁是一种基本的锁机制,在等待锁的
过程中,线程会一直处于自旋状态,即不会让出CPU,而是一直不停地检
测锁是否可用。自旋锁适用于代码执行时间很短,期待锁很快就可以被释
放的情况。自旋锁的实现通过设置一个标志位来指示锁的状态,如果锁处
于被占用状态,那么线程会不断地循环检测该标志位,直到锁的状态变为
可用。
2. 读写锁(reader-writer lock):读写锁是一种基于共享资源的
并发控制机制,它允许多个线程同时读取共享资源,但在写操作时,必须
互斥,即只允许一个线程进行写操作。读写锁适用于读操作频繁而写操作
较少的场景,可以提高系统的并发性能。读写锁的实现需要维护两个计数器,分别用于记录当前读操作的线程数和写操作的线程数。
3. 互斥锁(mutex):互斥锁是最常用的一种锁机制,也是最简单的
一种。互斥锁可以通过实现线程之间的互斥访问共享资源来保证数据的一
致性。在线程需要访问共享资源之前,会先尝试获取互斥锁,如果锁已经
被其他线程占用,那么线程就会进入阻塞状态,直到锁被释放。互斥锁可
以保证同时只有一个线程在访问共享资源,从而避免了竞态条件的发生。
4. 信号量(semaphore):信号量是一种更为复杂的锁机制,它可以
控制对共享资源的访问权限。信号量可以用来解决生产者-消费者问题、
读写者问题等。信号量分为二进制信号量(只能取0或1)和计数信号量(可以取多个非负整数)。线程可以通过等待(wait)操作来获取信号量,如果信号量的值大于0,那么线程可以继续执行,如果信号量的值等于0,
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
linux内核调度与spinlock的相互关系
嵌入式linux中文站关于自旋锁用法介绍的文章,已经有很多,但有些细节的地方点的还不够透,因此我们在这里将着重介绍自旋锁相关的知识。
一、自旋锁(spinlock)简介
自旋锁在同一时刻只能被最多一个内核任务持有,所以一个时刻只有一个线程允许存在于临界区中。这点可以应用在多处理机器、或运行在单处理器上的抢占式内核中需要的锁定服务。
二、信号量简介
这里也介绍下信号量的概念,因为它的用法和自旋锁有相似的地方。
Linux中的信号量是一种睡眠锁。如果有一个任务试图获得一个已被持有的信号量时,信号量会将其推入等待队列,然后让其睡眠。这时处理器获得自由去执行其它代码。当持有信号量的进程将信号量释放后,在等待队列中的一个任务将被唤醒,从而便可以获得这个信号量。
三、自旋锁和信号量对比
在很多地方自旋锁和信号量可以选择任何一个使用,但也有一些地方只能选择某一种。下面对比一些两者的用法。
表1-1自旋锁和信号量对比
应用场合
信号量or自旋锁
低开销加锁(临界区执行时间较快)
优先选择自旋锁
低开销加锁(临界区执行时间较长)
优先选择信号量
临界区可能包含引起睡眠的代码
不能选自旋锁,可以选择信号量