Linux下进程调度与优先级的深入分析

1)初识调度


为配合系统对进程的调度,采用两种方式进行处理
1.1)协同多任务处理

当进程因为事件的等待,而自动放弃CPU资源,而使其它进程得以使用CPU,这时称之为协同多任务处理.
其实如果进程都采用协同多任务处理时,系统将会轻松的调度进程,以分配资源

1.2)抢先式多任务处理
当进程不进行I/O,比如计算型运算应用时,一直占用大量的CPU时间,这时系统将会利用中断,使原占用CPU的进程放弃CPU.
这时称之为抢先式多任务处理

1.3)总结
1.3.1)UNIX/LINUX采用协同多任务处理与抢先式多任务处理相结合的方式处理进程.
1.3.2)当进程都采用协同多任务处理,系统就可能永远不会用到抢先式.
1.3.3)调度程序本身也是一个进程,PID是0,是INIT进行的父进程

 

 


2)阻塞,抢先占用和放弃


2.1)抢先占用的触发:

2.1.1)当一个进程因为它的时间片用完而被内核停止执行时,就说这个进程被抢占.
2.1.2)当一个享有更高优先公的进程在就绪队列,内核同样可以抢占正在执行的进程,即使它的时间片还没用完.


2.2)放弃的触发:
2.2.1)用户进程可以通过sched_yield系统调用来放弃使用CPU.
2.2.2)用户进程通过其它系统调用来放弃CPU.
例如:一个进程正在调用read/write时,它很可能不得不等待相应的设备的响应,这时它应用使自己睡眠(sleep),放弃CPU,直到设备就绪为止.


2.3)阻塞的触发:
2.3.1)当进程在内核模式下等待一个事件时,就是阻塞,直到所等侍的事件来唤醒它为止.

2.4)总结:
2.4.1)阻塞与放弃的区别
一个阻塞的进程即不会占用CPU,也不会被调度程序调度.而放弃的进程则会被调度程序调度.
2.4.2)linux2.6内核是一个可抢先占有的内核,在不可抢先有的内核则高优先级的进程不能抢占低优先级的进程.

 

 

3)优先级

3.1)动态优先级
因为高优先级的进程总比低优先级的进程先被调度,为防止有多个高优先级且一直占用CPU资源,导致其它进程不能占用CPU,所以引用动态优先级概念.

3.2)交互式的进程
如果某个进程被认为是交互式的,那么将被赋予较高的优先权,例如:键盘输入.交互式的进程从来不被抢占,并且占用CPU很少,它们常常自动放弃CPU.

3.3)有效优先级
进程的有效优先级就是静态优先级与额外值的和.

静态优先级是在系统创建时就已经分配给进程了,整个运行周期里不变.
额外值是一个可正可负的值,也可以把额外值理解为动态优先级,因为系统通过改变这个额外值(动态优先级)来改变进程的有效优先级.
额外值是由内核来管理

3.4)用一个例子来说明系统是如何给进程分配动态优先级的

新建nicegy脚本,这个脚本用sleep使其部分时间在睡眠状态.
#!/bin/sh
while true; do
 sleep .1
done

新建cruncher脚本,这个脚本在循环中使用true,一直占用CPU.
#!/bin/sh
while true; do
 true
done


新建脚本runex,这个脚本使行cruncher和niceguy两个脚本,监控这两个脚本的动态优先级.
#!/bin/sh

./cruncher &
./niceguy &


trap 'echo stoping; kill %1 %2; break' SIGINT

while true; do
        ps -C niceguy -C cruncher -o etime,pid,pri,cmd
        sleep .5
done

运行runex

./runex
    ELAPSED   PID PRI CMD
      00:00  2343  20 /bin/sh ./cruncher
      00:00  2344  21 /bin/sh ./niceguy
    ELAPSED   PID PRI CMD
      00:01  2343  20 /bin/sh ./cruncher
      00:01  2344  22 /bin/sh ./niceguy
    ELAPSED   PID PRI CMD
      00:01  2343  19 /bin/sh ./cruncher
      00:01  2344  22 /bin/sh ./niceguy
    ELAPSED   PID PRI CMD
      00:02  2343  18 /bin/sh ./cruncher
      00:02  2344  23 /bin/sh ./niceguy
    ELAPSED   PID PRI CMD
      00:02  2343  15 /bin/sh ./cruncher
      00:02  2344  23 /bin/sh ./niceguy
    ELAPSED   PID PRI CMD
      00:03  2343  14 /bin/sh ./cruncher
      00:03  2344  23 /bin/sh ./niceguy
    ELAPSED   PID PRI CMD
      00:04  2343  14 /bin/sh ./cruncher
      00:04  2344  23 /bin/sh ./niceguy
     
结论:
1)这两个进程会随时时间变化而变化
进程cruncher会一直运行不休眠(sleep),因此调度程序会给它一个负的额外值以降低它的有效优先级.
而进程niceguy大部从那时间则处于休息状态,因此调度程序会给它一个正的额外值以提高它的有效优先级.
2)而这两个进程在此之后就处于相对稳定的状态.
3)PRI是有效优先级,系统不能改变进程的静态优先级,但可以改变它的额外值以达到降低有效优先级的目的.
例如:静态优先级是20,额外值是-6,则有效优先级就是PRI=20+(-6)=14,注意这里没有涉及nice值,我们下面再来谈nice值对优先级的影响.

 

 


4)nice值与有效优先级

4.1)nice值的由来
内核允许用户通过使用一个名为nice的数值来影响调度程序关于优先级的调度
也就是说nice值是用户来触发,而我们上面说的额外值是内核来触发的.

4.2)nice值对有效优先级的影响

nice值越高,有效优先级就越低.
nice值越低,有效优先级就越高.
有效优先级=静态优先值+额外值-nice值
例如:
静态优先值为20
额外值为-6
nice值为-10
那最后有效优先级就是:
PRI=20+(-6)-(-10)=24
而如果nice值为10
PRI=20+(-6)-10=4


4.3)nice与有效优先级的范围

nice的范围是-20到19
有效优先级的范围是0-39


4.4)例子:nice是如何影响有效优先级的

cruncher进程的有效优先级是14,nice值是0

ps -C cruncher -o etime,pid,pri,ni,cmd
    ELAPSED   PID PRI  NI CMD
      00:17  6034  14   0 /bin/sh ./cruncher

更改nice值为-20
renice -20 -p 6034
6034: old priority 0, new priority -20

当nice的值为-20,PRI的值变成34
PRI = 静态优先级(20) + 附加值(-6) - nice(-20) = 34
ps -C cruncher -o etime,pid,pri,ni,cmd
    ELAPSED   PID PRI  NI CMD
      00:39  6034  34 -20 /bin/sh ./cruncher

更改nice的值为19
renice 19 -p 6034
6034: old priority -20, new priority 19

当nice的值为19,PRI的值为0
PRI = 静态优先级(20) + 附加值(-6) - nice(19) = 0 因为最低0,即使是-5最后也0

ps -C cruncher -o etime,pid,pri,ni,cmd
    ELAPSED   PID PRI  NI CMD
      01:03  6034   0  19 /bin/sh ./cruncher

注意:PRI为34时,系统的反应会变慢.

 

 

5)实时优先级

5.1)实时优先级概述:
linux提供了一个实时调度策略,提供了100个额外优先级别,以保证系统能及时响应进程.

5.2)实时优先级和普通优先级的区别:
实时优先级比普通优先级高,普通优先级是0-39.而实时优先级是(41-139),优先级一般不用40.

实时优先级在整个进程的生命周期里是不变的,所以实时进程没有nice值,也没有额外值.它的有效优先级就是静态优先级.

5.3)POSIX标准为实时进程指定了两种策略:先进先出(FIFO),时间片法(Round_Robin,简称RR)

5.3.1)先进先出(FIFO)调度
如果有两个同优先级的进程位于就绪队列,通常情况下,排在前面的先被执行

FIFO的策略要求进程不能抢占CPU,除非另一个实时进程有更高优先级

5.3.2)FIFO调度的例子
这个程序将永远不会退出.系统将会死机.

新建chewer脚本
#!/bin/sh
(sleep 50;kill -ALRM $$) &
while true;do
true;
done

程序为什么不在50秒之后退出呢,原因是一个fifo的调度,是不会运行(sleep 5;kill -ALRM $$),而永远进入了一个死循环.
在2.6.18的内核中,这个会造成死机,而新的2.6.32内核则不会,我们依然有机会终止它.
我们在2.6.32的内核中看下它的优先级

指定调度策略为FIFO,优先级为50
chrt -f 50 ./chewer &
[2] 2414

查看优先级,CLS显示了调度策略,chewer的调度策略是FF,FF表示FIFO,PTRPIO是实时优先级,这里chewer是50,
PRI是有效优先级,在实时系统里也叫绝对优先级,有效优先级是实时优先级与40的和,所以这里是90.

ps -eo pid,ppid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wchan:14,command
  PID  PPID   TID CLS RTPRIO  NI PRI PSR %CPU STAT WCHAN          COMMAND
    1     0     1 TS       -   0  19   0  0.0 Ss   poll_schedule_ init [2] 
    2     0     2 TS       -   0  19   0  0.0 S    kthreadd       [kthreadd]
    3     2     3 FF      99   - 139   0  0.0 S    migration_thre [migration/0]
    4     2     4 TS       -   0  19   0  0.0 S    ksoftirqd      [ksoftirqd/0]
    5     2     5 TS       -   0  19   0  0.0 S    worker_thread  [events/0]
    6     2     6 TS       -   0  19   0  0.0 S    worker_thread  [khelper]
   11     2    11 TS       -   0  19   0  0.0 S    async_manager_ [async/mgr]
   58     2    58 TS       -   0  19   0  0.0 S    bdi_sync_super [sync_supers]
   60     2    60 TS       -   0  19   0  0.0 S    bdi_forker_tas [bdi-default]
   62     2    62 TS       -   0  19   0  0.0 S    worker_thread  [kblockd/0]
   64     2    64 TS       -   0  19   0  0.0 S    worker_thread  [kacpid]
   65     2    65 TS       -   0  19   0  0.0 S    worker_thread  [kacpi_notify]
   66     2    66 TS       -   0  19   0  0.0 S    worker_thread  [kacpi_hotplug]
  118     2   118 TS       -   0  19   0  0.0 S    serio_thread   [kseriod]
  168     2   168 TS       -   0  19   0  0.0 S    kswapd         [kswapd0]
  169     2   169 TS       -   0  19   0  0.0 S    worker_thread  [aio/0]
  170     2   170 TS       -   0  19   0  0.0 S    worker_thread  [crypto/0]
  552     2   552 TS       -   0  19   0  0.0 S    scsi_error_han [scsi_eh_0]
  812     2   812 TS       -   0  19   0  0.0 S    kjournald      [kjournald]
  902     1   902 TS       -  -4  23   0  0.0 S<s  poll_schedule_ udevd --daemon
 1035     2  1035 TS       -   0  19   0  0.0 S    worker_thread  [kpsmoused]
 1551     2  1551 TS       -   0  19   0  0.0 S    worker_thread  [kstriped]
 1562     2  1562 TS       -   0  19   0  0.0 S    worker_thread  [ksnapd]
 1588     2  1588 TS       -   0  19   0  0.0 S    kjournald      [kjournald]
 1589     2  1589 TS       -   0  19   0  0.0 S    kjournald      [kjournald]
 1659     1  1659 TS       -   0  19   0  0.0 Ss   poll_schedule_ dhclient3 -pf /var/run/dhclient.eth0.pid -lf /var/lib/dhcp3/dhclie
 1675     1  1675 TS       -   0  19   0  0.0 Ss   poll_schedule_ /sbin/portmap
 1839     1  1839 TS       -   0  19   0  0.0 Sl   poll_schedule_ /usr/sbin/rsyslogd -c3
 1852     1  1852 TS       -   0  19   0  0.0 Ss   poll_schedule_ /usr/sbin/acpid
 2127     1  2127 TS       -   0  19   0  0.0 Ss   poll_schedule_ /usr/sbin/exim4 -bd -q30m
 2139     1  2139 TS       -   0  19   0  0.0 Ss   poll_schedule_ /usr/sbin/inetd
 2158     1  2158 TS       -   0  19   0  0.0 Ss   poll_schedule_ /usr/sbin/sshd
 2162     1  2162 TS       -   0  19   0  0.0 Ss   poll_schedule_ /sbin/rpc.statd
 2163  2158  2163 TS       -   0  19   0  0.0 Ss   poll_schedule_ sshd: root@pts/0,pts/1
 2172     1  2172 TS       -   0  19   0  0.0 Ss   hrtimer_nanosl /usr/sbin/atd
 2192     1  2192 TS       -   0  19   0  0.0 Ss   hrtimer_nanosl /usr/sbin/cron
 2206  2163  2206 TS       -   0  19   0  0.0 Ss   wait           -bash
 2211     1  2211 TS       -   0  19   0  0.0 Ss   poll_schedule_ /usr/sbin/apache2 -k start
 2228     1  2228 TS       -   0  19   0  0.0 Ss+  n_tty_read     /sbin/getty 38400 tty1
 2229     1  2229 TS       -   0  19   0  0.0 Ss+  n_tty_read     /sbin/getty 38400 tty2
 2230     1  2230 TS       -   0  19   0  0.0 Ss+  n_tty_read     /sbin/getty 38400 tty3
 2231     1  2231 TS       -   0  19   0  0.0 Ss+  n_tty_read     /sbin/getty 38400 tty4
 2232     1  2232 TS       -   0  19   0  0.0 Ss+  n_tty_read     /sbin/getty 38400 tty5
 2233     1  2233 TS       -   0  19   0  0.0 Ss+  n_tty_read     /sbin/getty 38400 tty6
 2236  2211  2236 TS       -   0  19   0  0.0 S    inet_csk_accep /usr/sbin/apache2 -k start
 2237  2211  2237 TS       -   0  19   0  0.0 S    inet_csk_accep /usr/sbin/apache2 -k start
 2238  2211  2238 TS       -   0  19   0  0.0 S    inet_csk_accep /usr/sbin/apache2 -k start
 2239  2211  2239 TS       -   0  19   0  0.0 S    inet_csk_accep /usr/sbin/apache2 -k start
 2240  2211  2240 TS       -   0  19   0  0.0 S    inet_csk_accep /usr/sbin/apache2 -k start
 2276  2163  2276 TS       -   0  19   0  0.0 Ss   wait           -bash
 2280  2276  2280 TS       -   0  19   0  0.1 S+   poll_schedule_ top
 2347     2  2347 TS       -   0  19   0  0.0 S    bdi_writeback_ [flush-8:0]
 2414  2206  2414 FF      50   -  90   0  112 R    -              /bin/sh ./chewer
 2415  2414  2415 FF      50   -  90   0  0.0 R    -              /bin/sh ./chewer
 

5.3.3)时间片调度(RR)

用时间片调度来执行chewer程序,则不会出现死机的情况.因为它在运行一段时间后,会根据时间片释放自己,这样就会fork出sleep进程,最后kill掉自己(chewer).

依然用chrt程序,-r表示用实时时间片调度,级别依然是50
chrt -r 50 ./chewer &

用ps命令查看有sleep 50的进程,同时chewer的调度状态CLS为RR
ps -eo pid,ppid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wchan:14,command
  PID  PPID   TID CLS RTPRIO  NI PRI PSR %CPU STAT WCHAN          COMMAND
    1     0     1 TS       -   0  19   0  0.0 Ss   poll_schedule_ init [2] 
    2     0     2 TS       -   0  19   0  0.0 S    kthreadd       [kthreadd]
    3     2     3 FF      99   - 139   0  0.0 S    migration_thre [migration/0]
    4     2     4 TS       -   0  19   0  0.0 S    ksoftirqd      [ksoftirqd/0]
    5     2     5 TS       -   0  19   0  0.0 S    worker_thread  [events/0]
    6     2     6 TS       -   0  19   0  0.0 S    worker_thread  [khelper]
   11     2    11 TS       -   0  19   0  0.0 S    async_manager_ [async/mgr]
   58     2    58 TS       -   0  19   0  0.0 S    bdi_sync_super [sync_supers]
   60     2    60 TS       -   0  19   0  0.0 S    bdi_forker_tas [bdi-default]
   62     2    62 TS       -   0  19   0  0.0 S    worker_thread  [kblockd/0]
   64     2    64 TS       -   0  19   0  0.0 S    worker_thread  [kacpid]
   65     2    65 TS       -   0  19   0  0.0 S    worker_thread  [kacpi_notify]
   66     2    66 TS       -   0  19   0  0.0 S    worker_thread  [kacpi_hotplug]
  118     2   118 TS       -   0  19   0  0.0 S    serio_thread   [kseriod]
  168     2   168 TS       -   0  19   0  0.0 S    kswapd         [kswapd0]
  169     2   169 TS       -   0  19   0  0.0 S    worker_thread  [aio/0]
  170     2   170 TS       -   0  19   0  0.0 S    worker_thread  [crypto/0]
  552     2   552 TS       -   0  19   0  0.0 S    scsi_error_han [scsi_eh_0]
  812     2   812 TS       -   0  19   0  0.0 S    kjournald      [kjournald]
  902     1   902 TS       -  -4  23   0  0.0 S<s  poll_schedule_ udevd --daemon
 1035     2  1035 TS       -   0  19   0  0.0 S    worker_thread  [kpsmoused]
 1551     2  1551 TS       -   0  19   0  0.0 S    worker_thread  [kstriped]
 1562     2  1562 TS       -   0  19   0  0.0 S    worker_thread  [ksnapd]
 1588     2  1588 TS       -   0  19   0  0.0 S    kjournald      [kjournald]
 1589     2  1589 TS       -   0  19   0  0.0 S    kjournald      [kjournald]
 1659     1  1659 TS       -   0  19   0  0.0 Ss   poll_schedule_ dhclient3 -pf /var/run/dhclient.eth0.pid -lf /var/lib/dhcp3/dhclie
 1675     1  1675 TS       -   0  19   0  0.0 Ss   poll_schedule_ /sbin/portmap
 1839     1  1839 TS       -   0  19   0  0.0 Sl   poll_schedule_ /usr/sbin/rsyslogd -c3
 1852     1  1852 TS       -   0  19   0  0.0 Ss   poll_schedule_ /usr/sbin/acpid
 2127     1  2127 TS       -   0  19   0  0.0 Ss   poll_schedule_ /usr/sbin/exim4 -bd -q30m
 2139     1  2139 TS       -   0  19   0  0.0 Ss   poll_schedule_ /usr/sbin/inetd
 2158     1  2158 TS       -   0  19   0  0.0 Ss   poll_schedule_ /usr/sbin/sshd
 2162     1  2162 TS       -   0  19   0  0.0 Ss   poll_schedule_ /sbin/rpc.statd
 2163  2158  2163 TS       -   0  19   0  0.0 Ss   poll_schedule_ sshd: root@pts/0,pts/1
 2172     1  2172 TS       -   0  19   0  0.0 Ss   hrtimer_nanosl /usr/sbin/atd
 2192     1  2192 TS       -   0  19   0  0.0 Ss   hrtimer_nanosl /usr/sbin/cron
 2206  2163  2206 TS       -   0  19   0  0.0 Ss   wait           -bash
 2211     1  2211 TS       -   0  19   0  0.0 Ss   poll_schedule_ /usr/sbin/apache2 -k start
 2228     1  2228 TS       -   0  19   0  0.0 Ss+  n_tty_read     /sbin/getty 38400 tty1
 2229     1  2229 TS       -   0  19   0  0.0 Ss+  n_tty_read     /sbin/getty 38400 tty2
 2230     1  2230 TS       -   0  19   0  0.0 Ss+  n_tty_read     /sbin/getty 38400 tty3
 2231     1  2231 TS       -   0  19   0  0.0 Ss+  n_tty_read     /sbin/getty 38400 tty4
 2232     1  2232 TS       -   0  19   0  0.0 Ss+  n_tty_read     /sbin/getty 38400 tty5
 2233     1  2233 TS       -   0  19   0  0.0 Ss+  n_tty_read     /sbin/getty 38400 tty6
 2236  2211  2236 TS       -   0  19   0  0.0 S    inet_csk_accep /usr/sbin/apache2 -k start
 2237  2211  2237 TS       -   0  19   0  0.0 S    inet_csk_accep /usr/sbin/apache2 -k start
 2238  2211  2238 TS       -   0  19   0  0.0 S    inet_csk_accep /usr/sbin/apache2 -k start
 2239  2211  2239 TS       -   0  19   0  0.0 S    inet_csk_accep /usr/sbin/apache2 -k start
 2240  2211  2240 TS       -   0  19   0  0.0 S    inet_csk_accep /usr/sbin/apache2 -k start
 2276  2163  2276 TS       -   0  19   0  0.0 Ss   wait           -bash
 2280  2276  2280 TS       -   0  19   0  0.1 S+   poll_schedule_ top
 2434     2  2434 TS       -   0  19   0  0.0 S    bdi_writeback_ [flush-8:0]
 2456  2206  2456 RR      50   -  90   0  141 R    -              /bin/sh ./chewer
 2457  2456  2457 RR      50   -  90   0  0.0 S    wait           /bin/sh ./chewer
 2458  2457  2458 RR      50   -  90   0  0.0 S    hrtimer_nanosl sleep 50
 2459  2206  2459 TS       -   0  19   0  0.0 R+   -              ps -eo pid,ppid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wc


注:
实时时间片调度进程的时间片与普通进程的时间片不一样,实时进程的时间片法,如果该进程被另一个更高优先级的进程抢占,
在高优先级执先完后,允许该进程用完剩余的时间片,如果普通进程则它的时间片将会缩短.

 

5.3.4)批处理调度(BATCH)
 
这种调度算法不是实时调度策略,这种调度策略和实时调度策略相反,因为只会在没有其他进程占用CPU时间时,它才会运行.
但与nice值设成最大不同,因为即便是优先权最低还是有可能轮到它.

下面指定批处理调度来运行chewer
chrt -b 0 ./chewer &
[1] 2508

可以看到chewer进程的CLS一列为B,它的实时优先级只能是0.
ps -eo pid,ppid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wchan:30,command
  PID  PPID   TID CLS RTPRIO  NI PRI PSR %CPU STAT WCHAN                          COMMAND
    1     0     1 TS       -   0  19   0  0.0 Ss   poll_schedule_timeout          init [2] 
    2     0     2 TS       -   0  19   0  0.0 S    kthreadd                       [kthreadd]
    3     2     3 FF      99   - 139   0  0.0 S    migration_thread               [migration/0]
    4     2     4 TS       -   0  19   0  0.0 S    ksoftirqd                      [ksoftirqd/0]
    5     2     5 TS       -   0  19   0  0.0 S    worker_thread                  [events/0]
    6     2     6 TS       -   0  19   0  0.0 S    worker_thread                  [khelper]
   11     2    11 TS       -   0  19   0  0.0 S    async_manager_thread           [async/mgr]
   58     2    58 TS       -   0  19   0  0.0 S    bdi_sync_supers                [sync_supers]
   60     2    60 TS       -   0  19   0  0.0 S    bdi_forker_task                [bdi-default]
   62     2    62 TS       -   0  19   0  0.0 S    worker_thread                  [kblockd/0]
   64     2    64 TS       -   0  19   0  0.0 S    worker_thread                  [kacpid]
   65     2    65 TS       -   0  19   0  0.0 S    worker_thread                  [kacpi_notify]
   66     2    66 TS       -   0  19   0  0.0 S    worker_thread                  [kacpi_hotplug]
  118     2   118 TS       -   0  19   0  0.0 S    serio_thread                   [kseriod]
  168     2   168 TS       -   0  19   0  0.0 S    kswapd                         [kswapd0]
  169     2   169 TS       -   0  19   0  0.0 S    worker_thread                  [aio/0]
  170     2   170 TS       -   0  19   0  0.0 S    worker_thread                  [crypto/0]
  552     2   552 TS       -   0  19   0  0.0 S    scsi_error_handler             [scsi_eh_0]
  812     2   812 TS       -   0  19   0  0.0 S    kjournald                      [kjournald]
  902     1   902 TS       -  -4  23   0  0.0 S<s  poll_schedule_timeout          udevd --daemon
 1035     2  1035 TS       -   0  19   0  0.0 S    worker_thread                  [kpsmoused]
 1551     2  1551 TS       -   0  19   0  0.0 S    worker_thread                  [kstriped]
 1562     2  1562 TS       -   0  19   0  0.0 S    worker_thread                  [ksnapd]
 1588     2  1588 TS       -   0  19   0  0.0 S    kjournald                      [kjournald]
 1589     2  1589 TS       -   0  19   0  0.0 S    kjournald                      [kjournald]
 1659     1  1659 TS       -   0  19   0  0.0 Ss   poll_schedule_timeout          dhclient3 -pf /var/run/dhclient.eth0.pid -lf /var/
 1675     1  1675 TS       -   0  19   0  0.0 Ss   poll_schedule_timeout          /sbin/portmap
 1839     1  1839 TS       -   0  19   0  0.0 Sl   poll_schedule_timeout         /usr/sbin/rsyslogd -c3
 1852     1  1852 TS       -   0  19   0  0.0 Ss   poll_schedule_timeout          /usr/sbin/acpid
 2127     1  2127 TS       -   0  19   0  0.0 Ss   poll_schedule_timeout          /usr/sbin/exim4 -bd -q30m
 2139     1  2139 TS       -   0  19   0  0.0 Ss   poll_schedule_timeout          /usr/sbin/inetd
 2158     1  2158 TS       -   0  19   0  0.0 Ss   poll_schedule_timeout          /usr/sbin/sshd
 2162     1  2162 TS       -   0  19   0  0.0 Ss   poll_schedule_timeout          /sbin/rpc.statd
 2163  2158  2163 TS       -   0  19   0  0.0 Ss   poll_schedule_timeout          sshd:root@pts/0,pts/1
 2172     1  2172 TS       -   0  19   0  0.0 Ss   hrtimer_nanosleep              /usr/sbin/atd
 2192     1  2192 TS       -   0  19   0  0.0 Ss   hrtimer_nanosleep              /usr/sbin/cron
 2206  2163  2206 TS       -   0  19   0  0.0 Ss   wait                           -bash
 2211     1  2211 TS       -   0  19   0  0.0 Ss   poll_schedule_timeout         /usr/sbin/apache2 -k start
 2228     1  2228 TS       -   0  19   0  0.0 Ss+  n_tty_read                     /sbin/getty 38400 tty1
 2229     1  2229 TS       -   0  19   0  0.0 Ss+  n_tty_read                     /sbin/getty 38400 tty2
 2230     1  2230 TS       -   0  19   0  0.0 Ss+  n_tty_read                     /sbin/getty 38400 tty3
 2231     1  2231 TS       -   0  19   0  0.0 Ss+  n_tty_read                     /sbin/getty 38400 tty4
 2232     1  2232 TS       -   0  19   0  0.0 Ss+  n_tty_read                     /sbin/getty 38400 tty5
 2233     1  2233 TS       -   0  19   0  0.0 Ss+  n_tty_read                     /sbin/getty 38400 tty6
 2236  2211  2236 TS       -   0  19   0  0.0 S    inet_csk_accept               /usr/sbin/apache2 -k start
 2237  2211  2237 TS       -   0  19   0  0.0 S    inet_csk_accept               /usr/sbin/apache2 -k start
 2238  2211  2238 TS       -   0  19   0  0.0 S    inet_csk_accept               /usr/sbin/apache2 -k start
 2239  2211  2239 TS       -   0  19   0  0.0 S    inet_csk_accept               /usr/sbin/apache2 -k start
 2240  2211  2240 TS       -   0  19   0  0.0 S    inet_csk_accept               /usr/sbin/apache2 -k start
 2276  2163  2276 TS       -   0  19   0  0.0 Ss   wait                           -bash
 2280  2276  2280 TS       -   0  19   0  0.1 S+   poll_schedule_timeout          top
 2491     2  2491 TS       -   0  19   0  0.0 S    bdi_writeback_task             [flush-8:0]
 2508  2206  2508 B        0   -  19   0 85.6 R    -                              /bin/sh ./chewer
 2509  2508  2509 B        0   -  19   0  0.0 S    wait                           /bin/sh ./chewer
 2510  2509  2510 B        0   -  19   0  0.0 S    hrtimer_nanosleep              sleep 50

 

 

6)chrt命令

chrt命令的用法:
可以指定进程的调度方法
6.1)--fifo or -f 表示先入先出策略
例如:
chrt --fifo 50 ./chewer &

6.2)--rr or -r 表示时间片策略
例如:
chrt --rr 50 ./chewer &

6.3)--batch or -b 表示批处理或空闲的策略
例如:
chrt --batch 0 ./chewer &

6.4)--other or -o 表示普通的分时进程
chrt --other 0 ./chewer &

--max or -m 可以打印出chrt分配优先级的范围
chrt --max

6.5)--pid or -p 可以打印出进程的调度策略及优先级

chrt  -p 2537
pid 2537's current scheduling policy: SCHED_RR
pid 2537's current scheduling priority: 50


6.6)用chrt命令测试优先级的抢占

根据上面的论述,高的优先级进程抢占低的优先级的进程,之所以用FIFO的策略,优先级别为50,会造成死机,这个进程的策略是最高的.
而又没有进程的优先级超过它,它自己又不会放弃或阻塞,所以会死机

那我们用更高的优先级来KILL它,可以吗?
答案是可以的.
还是那个程序.首先用时间片策略调度程序,优先级为50
chrt -r 50 ./chewer &

再用chrt指定它为fifo的策略,优先级为60,2563为它的进程号
chrt -f -p 60 2563

我们用ps查询sleep的PID为2565
ps -eo pid,ppid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wchan:14,command
2565  2564  2565 RR      50   -  90   0  0.0 R    -              sleep 50

再用chrt指定sleep的优先级为70
chrt -f -p 70 2565

这时程序在50秒后,就退出了.因为sleep是最高的,它kill掉了chewer

 

 

7)调度策略的总结

在进程调度中有四种方法,也就是四种类型的宏

普通的分时策略    TS  SCHED_OTHER
实时FIFO的策略    FF  SCHED_FIFO
实时时间片策略    RR  SCHED_RR
普通批处理策略   B  SCHED_BATCH

在三种状态可以在ps 命令的CLS列查出来
例如:
ps -eo pid,ppid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wchan:14,command

class代表CLS列
trprio代表实时优先级
ni代表nice,(在实时进程中无意思,所以为-)
pri代表绝对优先级,也就是有效优先级,在实时进程来说,绝对优先级是大于40
例如:指定fifo的优先级为1,绝对优先级就是41
chrt -f 1 ps -C ps -o pri,ni,rtprio,comm
PRI  NI RTPRIO COMMAND
 41   -      1 ps
wchan:14代表操作系统调用,14代表宽度为14个字符

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值