码迷,mamicode.com
首页 > 系统相关 > 详细

linux进程管理

时间:2015-09-05 19:29:33      阅读:311      评论:0      收藏:0      [点我收藏+]

标签:处理器   linux   上下文   优先级   经典的   

1 Linux进程管理

      进程管理是操作系统的最重要的功能之一。有效率的进程管理能保证一个程序平稳而高效地运行。
Linux的进程管理它包括进程调度、中断处理、信号、进程优先级、上下文切换、进程状态、进度内存等。
在这里,我们将描述Linux进程管理的基本原理的实现。它将更好地帮助你理解Linux内核如何处理进程及其对系统性能的影响。

2 什么是进程?
      一个进程是一个运行在处理器的程序的一个实例。该进程使用Linux内核能够处理的任何资源来完成它的任务。
所有运行在Linux操作系统中的进程都被task_struct结构管理,该结构同时被叫作进程描述。一个进程描述包含一个运行进程所有的必要信息,例如进程标识、进程属性和构建进程的资源。如果你了解该进程构造,你就能理解对于进程的运行和性能来说,什么是重要的。


每一个进程都有其生命周期,例如创建、运行、终止和消除。这些阶段会在系统启动和运行中重复无数次。因此,进程的生命周期对于其性能的分析是非常重要的。

下图展示了经典的进程生命周期。

技术分享

        当一个进程创建一个新的进程,进程的创建进程(父进程)调用一个fork()系统调用。当fork()系统调用被调用,它得到该新创建进程(子进程)的进程描述并调用一个新的进程id。它复制该值到父进程进程描述到子进程中。此时整个的父进程的地址空间是没有被复制的;父子进程共享相同的地址空间。

         exec()系统调用复制新的程序到子进程的地址空间。因为父子进程共享地址空间,写入一个新的程序的数据会引起一个分页错误。在这种情况下,内存会分配新的物理内存页给子进程。这个推迟的操作叫作写时复制。子进程通常运行他们自己的程序而不是与父进程运行相同的程序。这个操作避免了不必要的开销,因为复制整个地址空间是一个非常缓慢和效率低下的操作,它需要使用大量的处理器时间和资源。当程序已经执行完成,子进程通过调用exit()系统调用终止。exit()系统调用释放进程大部分的数据并通过发送一个信号通知其父进程。此时,子进程是一个被叫作僵尸进程的进程。子进程不会被完全移除直到其父进程知道其子进程的调用wait()系统调用而终止。当父进程被通知子进程终止,它移除子进程的所有数据结构并释放它的进程描述。

3 线程

一个线程是一个单独的进程生成的一个执行单元。它与其他的线程并行地运行在同一个进程中。各个线程可以共享进程的资源,例如内存、地址空间、打开的文件等等。它们能访问相同的程序数据集。线程也被叫作轻量级的进程(Light Weight Process,LWP)。因为它们共享资源,所以每个线程不应该在同一时间改变它们共享的资源。互斥的实现、锁、序列化等是用户程序的责任。

从性能的角度来说,创建线程的开销比创建进程少,因数创建一个线程时不需要复制资源。另一方面,进程和线程拥有在调度算法上有相似的特性。内核以相似的方式处理它们。

4 进程优先级和nice值
进程优先级是一个数值,它通过动态的优先级和静态的优先级来决定进程被CPU处理的顺序。一个拥有更高进程优先级的进程拥有更大的机率得到处理器的处理。

内核根据进程的行为和特性使用试探算法,动态地调整调高或调低动态优先级。一个用户进程可以通过使用进程的nice值间接改变静态优先级。一个拥有更高静态优先级的进程将会拥有更长的时间片(进程能在处理上运行多长时间)。

Linux支持从19(最低优先级)到-20(最高优先级)的nice值。默认值为0。把程序的nice值修改为负数(使进程的优先级更高),需要以root身份登陆或使用su命令以root身份执行。

5 上下文切换
在进程运行过程中,进程的运行信息被保存于处理器的寄存器和它的缓存中。正在执行的进程加载到寄存器中的数据集被称为上下文。为了切换进程,运行中进程的上下文将会被保存,接下来的运行进程的上下文将被被恢复到寄存器中。进程描述和内核模式堆栈的区域将会用来保存上下文。这个切换被称为上下文切换。过多的上下文切换是不受欢迎的,因为处理器每次都必须清空刷新寄存器和缓存,为新的进程制造空间。它可能会引起性能问题。

技术分享

6 中断处理
中断处理是优先级最高的任务之一。中断通常由I/O设备产生,例如网络接口卡、键盘、磁盘控制器、串行适配器等等。中断处理器通过一个事件通知内核(例如,键盘输入、以太网帧到达等等)。它让内核中断进程的执行,并尽可能快地执行中断处理,因为一些设备需要快速的响应。它是系统稳定的关键。当一个中断信号到达内核,内核必须切换当前的进程到一个新的中断处理进程。这意味着中断引起了上下文切换,因此大量的中断将会引起性能的下降。

在Linux的实现中,有两种类型的中断。硬中断是由请求响应的设备发出的(磁盘I/O中断、网络适配器中断、键盘中断、鼠标中断)。软中断被用于处理可以延迟的任务(TCP/IP操作,SCSI协议操作等等)。你可以在/proc/interrupts文件中查看硬中断的相关信息。

7 进程状态
每一个进程拥有自己的状态,状态表示了进程当前在发生什么。

在进程的执行期间进程的状态会发生改变。一些进程的状态如下:
TASK_RUNNING
在此状态下,表示进程正在CPU中运行或在队列中等待运行(运行队列)。

TASK_STOPPED
在此状态下的进程被某些信号(如SIGINT,SIGSTOP)暂停。进程正在等待通过一个信号恢复运行,例如SIGCONT。

TASK_INTERRUPTIBLE
在此状态下,进程被暂停并等待一个某些条件状态的到达。如果一个进程处于TASK_INTERRUPTIBLE状态并接收到一个停止的信号,进程的状态将会被改变并中断操作。一个典型的TASK_INTERRUPTIBLE状态的进程的例子是一个进程等待键盘中断。

TASK_UNINTERRUPTIBLE
与TASK_INTERRUPTIBLE相似。当一个进程处于TASK_UNINTERRUPTIBLE状态可以被中断,向处于TASK_UNINTERRUPTIBLE状态的进程发送一个信号不会发生任何操作。一个TASK_UNINTERRUPTIBLE进程的典型的例子是等待磁盘I/O操作。

TASK_ZOMBIE
当一个进程调用exit()系统调用退出后,它的父进程应该知道该进程的终止。处于TASK_ZOMBIE状态的进程会等待其父进程通知其释放所有的数据结构。

僵尸进程
当一个进程接收到一个信号而终止,它在结束自己之前,通常需要一些时间来结束所有的任务(例如关闭打开的文件)。在这个通常非常短暂的时间内,该进程就是一个僵尸进程。进程已经完成所有的关闭任务后,它会向父进程报告其即将终止。有些时候,一个僵尸进程不能把自己终止,这将会引导它的状态显示为z(zombie)。使用kill命令来关闭这样的一个进程是不可能的,因为该进程已经被认为已经死掉了。如果你不能清除僵尸进程,你可以结束其父进程,然后僵尸进程也随之消失。但是,如果父进程为init进程,你不能结束它。init进程是一个非常重要的进程,因此可能需要重启系统来清除僵尸进程。

9 Linux CPU调度
任何的计算机的基本功能都非常简单,就是计算。为了能够计算,它意味着必须管理计算资源或处理器和计算任务,也就是我们所知道的线程或进程。Linux内核使用一个O(1)的算法代替以前的O(n)的CPU调度算法。O(1)指的是一种静态的算法,意味着选择一个进程并执行所花费的时间是一个常数,不管进程的数量的大小。

新的调度算法的扩展性非常好,不管进程的数量或者处理器的数量是多少,系统的开销都是非常少的。该算法使用两个进程优先级数组:
active(活动的)
expired(过期的)

调度器根据进程的优先级和优先拦截率为进程分配时间片,然后进程以优先级顺序放置到active数组内。当进程时间片耗尽,进程申请一个新的时间片并放置到expired数组内。当active数组中的所有进程的时间片耗尽,这两个数组进行切换,重新运行该算法。对于一般的交互式进程(相对于实时进程),拥有高优先级的进程通常比低优先级的进程得到更长的时间片和更多的计算时间,但这并不表示低优先级的进程会被完全忽略(饿死)。该算法的优势是为拥有大量线程和进程并拥有多处理器的企业级环境提升Linux内核的扩展性。该O(1)的新CPU调度器是为内存2.6设计的,但是现在已经移植到2.4系列中。下图说明了Linux CPU如何调度工作。

技术分享

9.进程类型:
         守护进程: 在系统引导过程中启动的进程,跟终端无关的进程;
         前台进程:跟终端相关,通过终端启动的进程
                    注意:也可把在前台启动的进程送往后台,以守护模式运行;
          进程状态:
               运行态:running 
               就绪态:ready
               睡眠态:
                    可中断:interruptable,任何时刻都可以被调度,只要被需要到。
                   不可中断:uninterruptable,读取一个大文件时候,进程此刻处于的状态
属于不可中断进程。因为在读取大文件的时候,先是调用到内核内存,然后调用到进程内存,而在这段时间,进程是无法调度。

               停止态:暂停于内存中,但不会被调度,除非手动启动之;stopped
               僵死态:zombie:子进程完成父进程的任务,然后释放的过程。当父进程终止了,还有其他的进程,会成为他的父进程,如果没有父进程,就直接指定init为子进程的父进程。
          进程的分类:
               CPU-Bound:cup密集型,消耗cup比较多,而内存比较少。非交互型
               IO-Bound:iO密集型,消耗内存比较多,而cup占用率却比较少。交互型

10.进程查看及管理工具的使用:

           基本的管理工具有pstree, ps, pidof, pgrep, top, htop, glance, pmap, vmstat, dstat, kill, pkill, job, bg, fg, nohup,接下来我将分别简单介绍每一个命令的使用方法。

pstree:直接执行pstree命令得到下图的结构,可以很明显的看到系统当前的进程,以及父进程与子进程之间的关系。

技术分享

  ps 为我们提供了进程的一次性的查看,它所提供的查看结果并不动态连续的;如果想对进程时间监控,应该用top工具;
        linux系统各进程的相关信息均保存在/proc/PID目录下的各文件中;
        ps [OPTION]...
       选项:支持两种风格
             常用组合:aux
             u: 以用户为中心组织进程状态信息显示
             a: 与终端相关的进程;
             x: 与终端无关的进程;
技术分享
USER 进程的属主;

PID:进程的ID;
PPID:  父进程;
%CPU:进程占用的CPU百分比;
%MEM:占用内存的百分比;
NI:进程的NICE值,数值大,表示较少占用CPU时间,默认值为0;
VSZ: Virtual memory SiZe,虚拟内存集
RSS: ReSident Size, 常驻内存集
WCHAN:正在等待的进程资源
TTY:终端ID
STAT: 进程状态D    Uninterruptible sleep (usually IO)
R    正在运行可中在队列中可过行的;
S    处于休眠状态;
T    停止或被追踪;
Z    僵尸进程;
<  优先级高的进程
N  优先级较低的进程
+: 前台进程

  l: 多线程进程
  s: session leader,一个进程的领导者,下面有子进程

START:启动进程的时间

TIME:进程消耗cpu的时间
COMMAND:命令的名称和参数,包含在方括号里面的进程为内核进程

   常用组合:-ef
                   -e: 显示所有进程
                    -f: 显示完整格式程序信息

   常用组合:-eFH
                   -F: 显示完整格式的进程信息
                   -H: 以进程层级格式显示进程相关信息

技术分享      我们还可以自定义要显示的内容

      常用组合:-eo, axo
                         -eo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,comm
                         axo stat,euid,ruid,tty,tpgid,sess,pgrp,ppid,pid,pcpu,comm
假如,我们就显示一下这几个内容
                              ni: nice值
                              pri: priority,优先级
                              psr: processor, CPU,运行的cpu
                              rtprio: 实时优先级

ps axo ni,pri,psr,rtprio:

技术分享

 pgrep, pkill:显示指定用户的进程号,查看此进程是否正在运行。
                    pgrep [options] pattern
                      pkill [options] pattern
                           -u uid: effective user:有效用户ID
                           -U uid: real user:实际用户ID
                           -t terminal: 与指定终端相关的进程
                           -l: 显示进程名(仅pgrep)
                           -a: 显示完整格式的进程名(仅pkill)
                           -P pid: 显示其父进程为此处指定的进程的进程列表

技术分享

 pidof:
        根据进程名获取其PID;

技术分享 top:显示动态信息,动态刷新

技术分享

        监控界面为交互式界面,可使用一下命令对显示内容进行控制:    
            M:内存百分比;

            P:cup百分比:

            T:累计占用的CPU时间

             l:显示或者不显示负载信息

             t:显示或者不显示进程及其cpu相关的信息

             1:数字,分别显示每个cpu的相关信息

             q:退出

             k:终止指定进程

             s:修改刷新时间间隔

       选项:
                 -d #: 指定刷新时间间隔,默认为3秒;
                 -b: 以批次方式;
                 -n #: 显示多少批次;

       us:用户运行程序占用cpu的百分比

       sy:用于运行内核占用的cpu的百分比

       ni:用户进程空间所改变过优先级占用CPU的百分比

       id:idle,空闲cpu百分比

      hi:hardware interrupt ,硬中断占用cpu的百分比 

      si:soft inteerupt ,软中断占用cpu的百分比

      st:stolen,被虚拟化偷走的CPU的百分比
       wa:wait to I/O花费时间

以上这些是CPU相关的信息。

     Mem:物理内存

      Swap:交换分区

        buffers:缓冲区,用于减少进程之间的等待时间

        cache:cpu与内存之间的高速缓存,用于减少cpu的等待时间
            htop命令:
                 选项:
                      -d #: 指定延迟时间;
                      -u UserName: 仅显示指定用户的进程;
                      -s COLOMN: 以指定字段进行排序;
                 命令:
                      s: 跟踪选定进程的系统调用;
                      l: 显示选定进程打开的文件列表;
                      a:将选定的进程绑定至某指定CPU核心;     

                      t: 显示进程树


     htop命令:top的增强版,需要erpl源安装

技术分享                 选项:
                      -d #: 指定延迟时间;
                      -u UserName: 仅显示指定用户的进程;
                      -s COLOMN: 以指定字段进行排序;
                 命令:
                      s: 跟踪选定进程的系统调用;
                      l: 显示选定进程打开的文件列表;
                      a:将选定的进程绑定至某指定CPU核心;
                      t: 显示进程树

   vmstat命令:显示虚拟内存统计信息
          vmstat [options] [delay [count]]   

技术分享               procs:
                    r:等待运行的进程的个数;
                    b:处于不可中断睡眠态的进程个数;(被阻塞的队列的长度);
               memory:
                    swpd: 交换内存的使用总量;
                    free:空闲物理内存总量;
                    buffer:用于buffer的内存总量;
                    cache:用于cache的内存总量;
               swap:
                    si:数据进入swap中的数据速率(kb/s)
                    so:数据离开swap中的数据速率(kb/s)
               io:
                    bi:从块设备读入数据到系统的速率;(kb/s)
                    bo: 保存数据至块设备的速率;
               system:
                    in: interrupts, 中断速率;
                    cs: context switch, 进程切换速率;
            
   cpu:
                    us:用户空间占用的内存比例
                    sy:内核空间占据cpu的比例
                    id:空闲比例
                    wa:等待进程完成的时间比例
                    st:被虚拟化偷走的时间比例

          选项:
               -s: 显示内存的统计数据
技术分享  

   pmap命令:报告一个进程的内存映射表
               pmap [options] pid [...]
                    -x: 显示详细格式的信息;
               另外一种实现:  
                    # cat /proc/PID/maps

glances命令:
          glances [-bdehmnrsvyz1] [-B bind] [-c server] [-C conffile] [-p port] [-P password] [--password] [-t refresh] [-f file] [-o output]
技术分享
          内建命令:

技术分享        
  常用选项:
               -b: 以Byte为单位显示网卡数据速率;
               -d: 关闭磁盘I/O模块;
               -f /path/to/somefile: 设定输入文件位置;
               -o {HTML|CSV}:输出格式;
               -m: 禁用mount模块
               -n: 禁用网络模块
               -t #: 延迟时间间隔
               -1:每个CPU的相关数据单独显示;

          C/S模式下运行glances命令:
               服务模式:
                    glances -s -B IPADDR

                    IPADDR: 指明监听于本机哪个地址

               客户端模式:
                    glances -c IPADDR

                    IPADDR:要连入的服务器端地址

   
  dstat命令:显示系统资源统计信息
          dstat [-afv] [options..] [delay [count]]
技术分享               -c: 显示cpu相关信息;

               -c:显示cpu的统计数据
              -C :显示,一个,或者多个cup的统计数据

               -d: 显示disk相关信息;
               -D total,sda,sdb,...

                -i:显示中断的统计数据

                -l:显示系统负载的统计数据

               -g:显示page相关统计数据;
               -m: 显示memory相关统计数据;
               -n: 显示network相关统计数据;
               -p: 显示process相关统计数据;
               -r: 显示io请求相关的统计数据;
               -s: 显示swapped相关的统计数据;

         -v:相当于vmstat              

                --tcp
               --udp
               --unix
               --raw
               --socket

               --ipc:进程间通信

               --top-cpu:显示最占用CPU的进程;
               --top-io: 显示最占用io的进程;
               --top-mem: 显示最占用内存的进程;
               --top-lantency: 显示延迟最大的进程;

    
kill命令:

          向进程发送控制信号,以实现对进程管理

          显示当前系统可用信号:
               # kill -l  :显示当前可用信号
               # man 7 signal

               常用信号:
                    1) SIGHUP: 无须关闭进程而让其重读配置文件;
                    2) SIGINT: 中止正在运行的进程;相当于Ctrl+c;
                    9) SIGKILL: 杀死正在运行的进程;
                    15) SIGTERM:终止正在运行的进程;
                    18) SIGCONT:处于停止态,手动调度运行
                    19) SIGSTOP:处于停止态

               指定信号的方法:
                    (1) 信号的数字标识;1, 2, 9
                    (2) 信号完整名称;SIGHUP
                    (3) 信号的简写名称;HUP

         
向进程发信号:
               kill [-SIGNAL] PID...

          终止“名称”之下的所有进程:
               killall [-SIGNAL] Program
技术分享     Linux的作业控制
         jobs:
          前台作业:通过终端启动,且启动后一直占据终端;
          后台作业:可以通过终端启动,但启动后即转入后台运行(释放终端);

          如何让作业运行于后台?
               (1) 运行中的作业
                    Ctrl+z
               (2) 尚未启动的作业
                    # COMMAND &

               此类作业虽然被送往后台运行,但其依然与终端相关;如果希望送往后台后,剥离与终端的关系:
                    # nohup COMMAND &


         
      查看所有作业:
                    # jobs

               作业控制:
                    # fg [[%]JOB_NUM]:把指定的后台作业调回前台;
                    # bg [[%]JOB_NUM]:让送往后台的作业在后台继续运行;
                    # kill [%JOB_NUM]:终止指定的作业;百分号必须给

   
  进程优先级调整:
          静态优先级:100-139

          进程默认启动时的nice值为0,优先级为120;

          nice命令:
               nice [OPTION] [COMMAND [ARG]...]
               nice -n 5 htop,这是对于没有启动的进程的,如果进程启动了就得用renice这个命令
          renice命令:
               renice [-n] priority pid...是对已经处于运行状态的进程优先级的设置
技术分享         

   你也可以使用        ps axo pid,comm,ni  进行查看


              技术分享

以上这些内容就是我理解的进程管理,如有不适当,和不合理的地方,还请大家多多指教。

本文出自 “空白格” 博客,转载请与作者联系!

linux进程管理

标签:处理器   linux   上下文   优先级   经典的   

原文地址:http://lirui213.blog.51cto.com/4449582/1691583

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!