linux进程及运行状态分析

来源:互联网 发布:管理游戏的软件 编辑:程序博客网 时间:2024/06/05 10:46
1、进程与程序的概念:
进程:进程是在操作系统中运行的特定程序,或执行的任务。强调的是程序的运行过程,是动态的。
程序:程序是存储在磁盘上包含可执行机器指令和数据的静态实体。是静态的。

2、二者的相同点:
        参考自: http://net.pku.edu.cn/~yhf/lyceum/linuxK/tlk.html
       进程是一个随执行过程不断变化的实体。和程序要包含指令和数据一样,进程也包含程序计数器和所有CPU寄存器的值,同时它的堆栈中存储着如子程序参数、返回地址以及变量之类的临时数据。

3、Linux进程
        参考 :http://blog.csdn.net/npy_lp/article/details/7292563      
        为了让Linux来管理系统中的进程,每个进程用一个task_struct数据结构来表示(任务与进程在Linux中可以混用)。数组task包含指向系统中所有task_struct结构的指针。
       这意味着系统中的最大进程数目受task数组大小的限制,缺省值一般为512。创建新进程时,Linux将从系统内存中分配一个task_struct结构并将其加入task数组。  当前运行进程的结构用current指针来指示。
       管理进程的结构体task_struct的定义在:linux-2.6.30.4/include/linux/sched.h 中,如下所示:

struct task_struct {    volatile long state;    /* -1 unrunnable, 0 runnable, >0 stopped */    void *stack;    atomic_t usage;    unsigned int flags;    /* per process flags, defined below */    unsigned int ptrace;    int lock_depth;        /* BKL lock depth */    ...........      int exit_state;    .........    .........};

3.1 进程的状态 state

1、进程状态定义

volatile long state;int exit_state;

2、state成员的可能取值如下:

#define TASK_RUNNING        0#define TASK_INTERRUPTIBLE    1#define TASK_UNINTERRUPTIBLE    2#define __TASK_STOPPED        4#define __TASK_TRACED        8/* in tsk->exit_state */#define EXIT_ZOMBIE        16#define EXIT_DEAD        32/* in tsk->state again */#define TASK_DEAD        64#define TASK_WAKEKILL        128#define TASK_WAKING        256

3、相关状态的解释。

     系统中的每个进程都必然处于以上所列进程状态中的一种。

    TASK_RUNNING :运行态或就绪态。表示进程要么正在执行,要么正要准备执行。

    TASK_INTERRUPTIBLE :浅睡眠状态。表示进程被阻塞。能响应信号,直到被唤醒,进程的状态就被设置为 TASK_RUNNING。

    TASK_UNINTERRUPTIBLE :深睡眠状态。的意义与TASK_INTERRUPTIBLE类似,无法响应信号。

                                                    该进程等待一个事件的发生或某种系统资源。

    __TASK_STOPPED :停止态 。表示进程被停止执行。

    __TASK_TRACED : 对于进程本身来说,TASK_STOPPED和TASK_TRACED状态很类似,都是表示进程暂停下来。
                                    而TASK_TRACED状态相当于在TASK_STOPPED之上多了一层保护,处于TASK_TRACED状态
                                         的进程不能响应SIGCONT信号而被唤醒。只能等到调试进程通过ptrace系统调用执行PTRACE_CONT、
                                         PTRACE_DETACH等操作(通过ptrace系统调用的参数指定操作),或调试进程退出,
                                          被调试的进程才能恢复TASK_RUNNING状态。

    EXIT_ZOMBIE :僵尸态。此时进程不能被调度,但是PCB 未被释放。

    EXIT_DEAD :死亡态。表示一个已终止的进程,其PCB被释放。

    EXIT_ZOMBIE和EXIT_DEAD 也可以存放在 exit_state 成员中。进程状态的切换过程和原因大致如下图(图片来自《Linux Kernel Development》):




4、关于进程的挂起与阻塞
       本人的理解是:进程的阻塞对应的是:TASK_INTERRUPTIBLE  或者 TASK_UNINTERRUPTIBLE 这两种状态,一般是被动产生的,
       而挂起状态则一般是通过相应函数去主动使进程挂起的。

        以下是网上相关说法理解,本人认为分析得比较清晰的一个版本:
        来源:http://blog.csdn.net/neomanontheway/article/details/5764660  
  • 理解一:挂起是一种主动行为,因此恢复也应该要主动完成,而阻塞则是一种被动行为,是在等待事件或资源时任务的表现,你不知道他什么时候被阻塞(pend),也就不能确切的知道他什么时候恢复阻塞。而且挂起队列在操作系统里可以看成一个,而阻塞队列则是不同的事件或资源(如信号量)就有自己的队列。
  • 理解二:阻塞(pend)就是任务释放CPU,其他任务可以运行,一般在等待某种资源或信号量的时候出现。挂起(suspend)不释放CPU,如果任务优先级高就永远轮不到其他任务运行,一般挂起用于程序调试中的条件中断,当出现某个条件的情况下挂起,然后进行单步调试。
  • 理解三:pend是task主动去等一个事件,或消息.suspend是直接悬挂task,以后这个task和你没任何关系,任何task间的通信或者同步都和这个suspended task没任何关系了,除非你resume task;
  • 理解四:任务调度是操作系统来实现的,任务调度时,直接忽略挂起状态的任务,但是会顾及处于pend下的任务,当pend下的任务等待的资源就绪后,就可以转为ready了。ready只需要等待CPU时间,当然,任务调度也占用开销,但是不大,可以忽略。可以这样理解,只要是挂起状态,操作系统就不在管理这个任务了。
  • 理解五:挂起是主动的,一般需要用挂起函数进行操作,若没有resume的动作,则此任务一直不会ready。而阻塞是因为资源被其他任务抢占而处于休眠态。两者的表现方式都是从就绪态里“清掉”,即对应标志位清零,只不过实现方式不一样。

0 0