Linux进程状态与调度
Linux2 调度进程

Linux2 调度进程在Fedora Core Linux系统中,允许多个进程并发执行。
但是,通常情况下,系统中的资源总是有限的,如果系统中并发执行的进程数量过多,就会造成系统的整体性能下降,尤其是当系统中存在黑客进程或者病毒进程时,甚至可能会造成系统瘫痪。
因而,有必要根据一定的策略对系统中的进程进行调度,例如,将可疑的进程终止,将不紧急的进程挂起或者降低其优先级等。
系统管理员或者普通用户都可以对进程进行调度,但是执行这种操作时要非常小心,因为有些进程是与系统运行相关联的,不能对它们有错误的调度。
可以使用如下所示的任一种方法进行进程调度:●在系统监视器的“进程”选项页中进行调度。
●在top命令的执行过程中使用交互命令进行调度。
●在命令行中直接执行各种调度进程的命令。
下面将介绍如何使用命令行命令调度进程。
1.更改进程的优先级在fedora系统中,各个进程都是具有特定的优先级的,系统在为某个进程分配CPU使用时间时是根据进程的优先级进行判定的。
有些进程比较重要,需要先执行,以提高整个程序的执行效率,而有些不太重要的进程,其优先级可以低一些。
通常情况下,大多数用户进程的优先级是相同的,但是可以使用Fedora提供的某些命令改变进程的优先级。
通过执行“ps -l”命令可以查看当前用户进程的优先级,如下所示。
PRI表示进程的优先级,它是由操作系统动态计算的,是实际的进程优先级;NI所表示的是请求进程执行优先级,它可由进程拥有者或者超级用户进行设置,NI会影响到实际的进程优先级。
下面介绍两个可以改变进程优先级的命令。
(1)nice命令格式:nice 【选项】命令功能:在启动进程时指定请求进程执行优先级。
该命令较常用的一个选项是“-n”,n值(即NI值)的范围是从-20到19。
-20代表最高的NI优先级,19代表最低的NI优先级。
如果没有该参数,将自动设置NI值为10。
默认情况下,只有超级用户才有权提高请求进程的优先级,而普通用户只能降低请求进程的优先级。
Linux进程状态解析之R、S、D、T、Z、X

Linux进程状态解析之R、S、D、T、Z、XLinux是一个多用户,多任务的系统,可以同时运行多个用户的多个程序,就必然会产生很多的进程,而每个进程会有不同的状态。
众所周知,现在的分时操作系统能够在一个CPU上运行多个程序,让这些程序表面上看起来是在同时运行的。
linux就是这样的一个操作系统。
在linux系统中,每个被运行的程序实例对应一个或多个进程。
linux内核需要对这些进程进行管理,以使它们在系统中“同时”运行。
linux内核对进程的这种管理分两个方面:进程状态管理,和进程调度。
本文主要介绍进程状态管理,进程调度见《linux进程调度浅析》。
Linux进程状态:R (TASK_RUNNING),可执行状态。
只有在该状态的进程才可能在CPU上运行。
而同一时刻可能有多个进程处于可执行状态,这些进程的task_struct结构(进程控制块)被放入对应CPU的可执行队列中(一个进程最多只能出现在一个CPU的可执行队列中)。
进程调度器的任务就是从各个CPU的可执行队列中分别选择一个进程在该CPU上运行。
很多操作系统教科书将正在CPU上执行的进程定义为RUNNING状态、而将可执行但是尚未被调度执行的进程定义为READY状态,这两种状态在linux下统一为 TASK_RUNNING状态。
只要可执行队列不为空,其对应的CPU就不能偷懒,就要执行其中某个进程。
一般称此时的CPU“忙碌”。
对应的,CPU“空闲”就是指其对应的可执行队列为空,以致于CPU无事可做。
有人问,为什么死循环程序会导致CPU占用高呢?因为死循环程序基本上总是处于TASK_RUNNING状态(进程处于可执行队列中)。
除非一些非常极端情况(比如系统内存严重紧缺,导致进程的某些需要使用的页面被换出,并且在页面需要换入时又无法分配到内存……),否则这个进程不会睡眠。
所以 CPU的可执行队列总是不为空(至少有这么个进程存在),CPU也就不会“空闲”。
理解Linux的进程调度和优先级

理解Linux的进程调度和优先级Linux是一种广泛使用的开源操作系统,它采用了多任务处理的方式,能够同时运行多个进程。
进程调度是Linux操作系统中非常重要的一部分,它决定了进程之间如何共享CPU资源,使得操作系统能够高效地运行。
进程调度是操作系统的核心功能之一,它负责按照一定的调度算法从就绪队列中选择一个进程并将其分配给CPU执行。
Linux操作系统采用了时间片轮转法作为默认的调度算法,即每个进程被分配一个时间片,当时间片用完之后,如果进程还未执行完毕,就会被挂起,将执行机会分配给下一个就绪进程。
这样可以保证多个进程之间的平等性,防止某个进程长时间占用CPU资源。
除了时间片轮转法,Linux操作系统还支持其他的调度算法,如优先级调度、实时调度等。
优先级调度是一种根据进程的优先级来进行调度的方法,优先级高的进程会优先获得CPU执行权。
在Linux中,每个进程都有一个静态优先级和一个动态优先级,静态优先级由进程创建时指定,而动态优先级会根据进程执行情况进行动态调整。
实时调度是一种对实时任务进行优先调度的方法,可以保证实时任务的响应时间。
Linux操作系统中,进程的优先级范围是-20到19,数值越小表示优先级越高。
根据进程的优先级,Linux操作系统按照先运行高优先级进程的原则来进行调度。
当有多个具有相同优先级的进程时,Linux会采用时间片轮转法来进行调度。
通过灵活调整进程的优先级,可以合理分配CPU资源,提高系统的整体性能和响应速度。
除了优先级调度算法外,Linux操作系统还支持实时调度算法。
实时任务对响应时间要求非常高,需要保证任务在规定的时间内完成。
为了实现实时调度,Linux操作系统引入了实时进程和实时调度策略。
实时进程是一类对时间敏感的进程,它们可以获得更高的执行优先级和更快的响应时间。
实时进程的调度策略有FIFO(先进先出)调度、循环调度等。
理解Linux的进程调度和优先级对于系统管理员和开发人员来说非常重要。
Linux线程的状态与调度

Linux线程的状态与调度1,线程的⽣命周期线程从创建、运⾏到结束总是处于下⾯五个状态之⼀:新建状态、就绪状态、运⾏状态、阻塞状态及死亡状态。
1.新建状态(New):当⽤new操作符创建⼀个线程时,例如new Thread(r),线程还没有开始运⾏,此时线程处在新建状态。
当⼀个线程处于新⽣状态时,程序还没有开始运⾏线程中的代码2.就绪状态(Runnable)⼀个新创建的线程并不⾃动开始运⾏,要执⾏线程,必须调⽤线程的start()⽅法。
当线程对象调⽤start()⽅法即启动了线程,start()⽅法创建线程运⾏的系统资源,并调度线程运⾏run()⽅法。
当start()⽅法返回后,线程就处于就绪状态。
处于就绪状态的线程并不⼀定⽴即运⾏run()⽅法,线程还必须同其他线程竞争CPU时间,只有获得CPU时间才可以运⾏线程。
因为在单CPU的计算机系统中,不可能同时运⾏多个线程,⼀个时刻仅有⼀个线程处于运⾏状态。
因此此时可能有多个线程处于就绪状态。
对多个处于就绪状态的线程是由Java运⾏时系统的线程调度程序(thread scheduler)来调度的。
3.运⾏状态(Running)当线程获得CPU时间后,它才进⼊运⾏状态,真正开始执⾏run()⽅法.4. 阻塞状态(Blocked)线程运⾏过程中,可能由于各种原因进⼊阻塞状态:1>线程通过调⽤sleep⽅法进⼊睡眠状态;2>线程调⽤⼀个在I/O上被阻塞的操作,即该操作在输⼊输出操作完成之前不会返回到它的调⽤者;3>线程试图得到⼀个锁,⽽该锁正被其他线程持有;4>线程在等待某个触发条件;......所谓阻塞状态是正在运⾏的线程没有运⾏结束,暂时让出CPU,这时其他处于就绪状态的线程就可以获得CPU时间,进⼊运⾏状态。
5. 死亡状态(Dead)有两个原因会导致线程死亡:1) run⽅法正常退出⽽⾃然死亡,2) ⼀个未捕获的异常终⽌了run⽅法⽽使线程猝死。
电子科技大学 UNIX_Linux操作系统内核结构6章

一个进程的上下文包括五个方面: ①、被进程正文所定义的进程状态 ②、进程所使用的全局变量和数据结构的值 ③、机器寄存器的值 ④、进程表项proc结构和user结构中的值 ⑤、用户堆栈和核心堆栈中的值
“执行一个进程”——指系统在该进程的上下文中执行, 也就是进程的上下文确定和限制了进程的运行环境和空间。
可以随进程状态的变化而在内外存之间交换的进程控制信 息中的其余部分。
为了方便进程映像在内外之间交换,UNIX系统中把进程非 常驻内存部分作为一个整体,占用连续的存贮区,其顺序是: 首先是user结构(进程扩充控制块)和核心栈,然后是数据段 和用户栈。
16
进程user结构和核心栈合并构成进程的“本进程数据区— —ppda区(per process data area)。
15
在进程映像占用的内存被分配给其他进程之前,不但该进 程的程序和数据需要调出内存,该进程的控制信息也被调出内 存。但为了该进程能够再次被调入内存,内存中需要保留一部 分必要的信息,这就把进程控制信息也分成了常驻内存和非常 驻内存两部分: 常驻内存控制信息块
是系统需要经常查询以及恢复整个进程映象时所不可缺少 的信息。 非常驻内存控制信息块
7
3、进程的解释
在UNIX系统中进程的概念包含什么意义?
在较高级的方面 进程是一个重要的组织概念。可以把计算机系统看作是若
干进程组合的活动。进程是系统中活动的实体,它可以生成和 消灭,申请和释放资源,可以相互合作和竞争,而真正活动的 部件如处理机和外部设备则是看不见的。
在较低级方面 进程是不活动的实体,而处理机则是活动的,处理机的任
核心从一个进程转到另一个进程执行时,叫做“上下文切
换”,也就是系统从一个进程上下文确定的环境换到另一个进
linux的任务调度机制

linux的任务调度机制摘要:1.Linux任务调度机制简介2.Linux任务调度器的工作原理3.调度策略和队列4.进程优先级和调度算法5.总结正文:Linux任务调度机制是操作系统中负责分配处理器时间片给各个进程的核心组件。
它依据特定的策略和算法,确保公平、高效地管理进程的执行。
本文将详细介绍Linux任务调度机制的各个方面。
1.Linux任务调度机制简介Linux采用基于优先级的抢占式调度算法,以确保处理器资源得到充分利用。
调度器通过周期性地在就绪队列中选择一个或多个进程,将它们分配给处理器执行。
调度器主要依据进程的优先级和当前的负载情况来决定哪个进程获得处理器资源。
2.Linux任务调度器的工作原理Linux任务调度器的核心组件是调度实体(scheduler entity),它包括进程队列、调度策略和调度算法。
调度实体根据系统的当前状态,按照策略和算法来选择下一个要执行的进程。
调度实体的工作过程分为以下几个步骤:- 进程创建:当一个新进程被创建时,调度器会为其分配一个初始优先级,并将其加入就绪队列。
- 进程执行:调度器从就绪队列中选择一个或多个进程,将它们分配给处理器执行。
执行过程中,进程可能因时间片用完或被阻塞而放弃处理器资源。
- 进程更新:调度器周期性地更新进程的优先级和状态,以反映其当前的执行情况。
- 进程退出:当进程完成执行或被终止时,调度器会将其从进程队列中移除。
3.调度策略和队列Linux调度器支持多种调度策略,如FIFO(先进先出)、SJF(短作业优先)和RR(时间片轮转)。
调度策略决定了进程在队列中的排列顺序,从而影响了调度器选择下一个进程的依据。
Linux中有两个主要的进程队列:就绪队列和运行队列。
就绪队列包含了所有等待处理器资源的进程,而运行队列则存放了当前正在执行的进程。
调度器会根据策略从就绪队列中选择一个或多个进程,将其加入运行队列。
4.进程优先级和调度算法Linux中的进程优先级是一个0-139的整数,优先级数值越低,进程获得处理器资源的机会越高。
linux下常见的调度策略及调度原理

linux下常见的调度策略及调度原理Linux是一种开源的操作系统,广泛应用于服务器和嵌入式设备中。
在Linux系统中,进程调度策略是操作系统的核心组成部分之一,它决定了进程的执行顺序和时间分配。
本文将介绍Linux下常见的调度策略及其调度原理。
在Linux系统中,常见的进程调度策略包括先来先服务(FCFS)、最短作业优先(SJF)、时间片轮转(RR)和优先级调度(Priority Scheduling)等。
先来先服务(FCFS)是一种简单而直观的调度策略,它按照进程到达的先后顺序进行调度。
即当一个进程到达系统时,它将被放入就绪队列的末尾,并等待CPU的分配。
当CPU空闲时,系统将选择就绪队列中的第一个进程分配给CPU执行。
这种调度策略的优点是公平性强,但缺点是无法处理长作业和短作业的差异,容易产生"饥饿"现象。
最短作业优先(SJF)调度策略是根据进程的执行时间来决定优先级的调度策略。
即系统会选择执行时间最短的进程先执行,以减少平均等待时间。
这种调度策略的优点是能够最大程度地减少平均等待时间,但缺点是可能会出现长作业等待时间过长的问题。
时间片轮转(RR)是一种基于时间片的调度策略,每个进程被分配一个固定长度的时间片。
当一个进程的时间片用完时,系统将把CPU分配给下一个进程。
这种调度策略的优点是能够有效地平衡进程之间的响应时间,但缺点是可能会导致频繁的上下文切换。
优先级调度(Priority Scheduling)是一种根据进程优先级来决定调度顺序的策略。
每个进程被分配一个优先级,优先级越高的进程越容易被调度执行。
这种调度策略的优点是能够根据不同进程的需求进行灵活调度,但缺点是可能会导致低优先级进程的"饥饿"问题。
在Linux系统中,调度算法的实现是通过内核的进程调度器来完成的。
内核中的调度器会根据不同的调度策略来选择下一个要执行的进程,并将其上下文切换到CPU中执行。
深入解读Linux进程调度Schedule【转】

深⼊解读Linux进程调度Schedule【转】调度系统是现代操作系统⾮常核⼼的基础⼦系统之⼀,尤其在多任务并⾏操作系统(Multitasking OS)上,系统可能运⾏于单核或者多核CPU上,进程可能处于运⾏状态或者在内存中可运⾏等待状态。
如何实现多任务同时使⽤资源并且提供给⽤户及时的响应实现实时交互以及提供⾼流量并发等对现代操作系统的设计实现带来了巨⼤挑战,⽽Linux调度⼦系统的设计同样需要实现这些看似⽭盾的要求,适应不同的使⽤场景。
我们看到Linux是⼀个复杂的现在操作系统,各个⼦系统之间相互合作才能完成⾼效的任务。
本⽂从围绕调度⼦系统,介绍了调度⼦系统核⼼的概念,并且将其与Linux各个相关组件的关系进⾏探讨,尤其是与调度⼦系统息息相关的中断(softirq和irq)⼦系统以及定时器Timer,深⼊⽽全⾯地展⽰了调度相关的各个概念以及相互联系。
由于笔者最近在调试PowerPC相关的芯⽚,因此相关的介绍会以此为例提取相关的内核源代码进⾏解读展⽰。
涉及的代码为Linux-4.4稳定发布版本,读者可以查看源码进⾏对照。
1. 相关概念要理解调度⼦系统,⾸先需要总体介绍调度的流程,对系统有⼀个⾼屋建瓴的认识之后,再在整体流程中对各个节点分别深⼊分析,从⽽掌握丰富⽽饱满的细节。
在系统启动早期,会注册硬件中断,时钟中断是硬件中断中⾮常重要的⼀种,调度过程中需要不断地刷新进程的状态以及设置调度标志已决定是否抢占进程的执⾏进⾏调度。
时钟中断就是周期性地完成此项⼯作。
这⾥⼜引出另外⼀个现代OS的调度设计思想即抢占(preempt),⽽与其对应的概念则为⾮抢占或者合作(cooperate),后⾯会给出两者的详细区别。
时钟中断属于硬件中断,Linux系统不⽀持中断嵌套,所以在中断发⽣时⼜会禁⽌本地中断(local_irq_disable),⽽为了尽快相应其他可能的硬件事件,必须要尽快完成处理并开启中断,因此引出了中断下半部,也就是softirq的概念。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Linux进程状态与调度
目录
一.进程的状态
1.schedule_timeout
2.wake_up
3.task_struct current
二.内核与用户空间信号传递fasync
一.进程的状态
1.Schedule_timeout
当我们调用schedule_timeout时,有两种情况能打断该定时器,一种为超时,一种为有信号打断。
在该函数的申明中提到
* %TASK_INTERRUPTIBLE - the routine may return early if a signal is
* delivered to the current task. In this case the remaining time
* in jiffies will be returned, or 0 if the timer expired in time
*
* The current task state is guaranteed to be TASK_RUNNING when this
* routine returns.
配合schedule_timeout,使用__set_currnet_state.对于支持信号打断的schedule_timeout,调用__set_currnet_state设置task state 为
TASK_INTERRUPIBLE,如下,
__set_current_state(TASK_INTERRUPTIBLE);
Timeout=schedule_timeout(timeout);
__set_current_state(TASK_RUNNING);
调用schedule_timeout如果超时之后会自动设置task_state为
TASK_RUNNING,在调用schedule_timeout之后,进程会进入休眠状态,退出进程调度,只有在有关于此进程的事件到来时会被唤醒(各种信号),重新加入进程调度中。
用过msleep都知道所在的task会sleep 相应ms,而实际上其原理就与schedule_timeout和进程状态有关。
当设置current_state为TASK_UNINTERRUPTIBLE时,只能等待超时,signal 无法打断
这就是msleep的原理,msleep调用的函数为schedule_timeout_uninterruptible() 如下,
signed long __sched schedule_timeout_uninterruptible(signed long timeout)
{
__set_current_state(TASK_UNINTERRUPTIBLE);
return schedule_timeout(timeout);
}
2.Wake_up
schedule_timeout会被信号唤醒,那么具体是如何操作的?
以Linux kernel中的n_tty.c中的n_tty_read函数为例,
Wait_queue_head_t read_wait
Init_waitqueue_head(&tty->read_wait)
DECLARE_WAITQUEUE(wait,current); //初始化一个wait_queue_t wait ,task 为current
add_wait_queue(&tty->read_wait,&wait);//将wait添加到read_wait队列中去if(waitqueue_active(&tty->read_wait)) //判断read_wait是否为空
wake_up_interruptible(&tty->read_wait) // 唤醒等待队列
这里唤醒的是自己定义的read_wait队列,在wake_up_interruptible中,会将该进程重新加入run_queue中进行调度(实际调用的是try_to_wake_up函数),这样schedule_timeout被打断。
以上就是schedule_timeout(schedule())和wake_up的应用,实际上很多机制如wait_event_interrupt,wake_event_interrupt,wait_for_completion,complete 等机制都是在这些基础上封装而实现的机制。
3.Task_struct Current
Current是一个很重要的task_struct,代码部分通过thread_info->task得到,而thread_info通过current_thread_info()得到,这是在2.6之后的一个设计,current_thread_info()代码如下,
static inline struct thread_info *current_thread_info(void)
{
register unsigned long sp asm ("sp");
return (struct thread_info *)(sp & ~(THREAD_SIZE - 1));
}
THREAD_SIZE 8192 or 4096
因为每一个进程都一个自己的堆栈(4K or 8K),而SP寄存器只有一个,当进行调度时,会将一个进程堆栈的SP 转换到另一个进程的SP,而SP寄存器永远为当前运行的进程的SP值。
而每一个进程堆栈的低地址(12位或者13位)就存放了该进程的thread_info 起始的信息。
这是内核进程的堆栈空间,空间大小固定,必须物理地址连续,溢出为固定堆栈大小溢出。
而对应用户空间进程而言,它的堆栈空间可大可小,并且物理地址可以不连续(由MMU管控),出现溢出问题的时候有可能用户空间进程本身没有问题,而溢出部分将用户空间的其他进程的堆栈进行了修改导致这些进程运行出现错误。
二.fasync
使用fasync实现内核信号到用户空间的信号传递(比uevent简单)
内核部分:(以tty为例)
Struct fasync_struct *fasync;
在tty_fasync(int fd,struct file *filp,int on)中
Fasync_helper(fd,filp,on,&tty->fasync);//init fasync
当需要发送信号给用户空间时,调用
Kill_fasync(&tty->fasync,SIGIO,POLL_IN);
Kill_fasync(&tty->fasync,SIGIO,POLL_OUT);
用户空间:
利用signal或者signaction设置SIGIO信号处理的函数
Fcntl F_SETOWN设置当前进程为设备文件owner
Fcntl F_SETFL指令设置FASYNC指令。