Linux进程管理与调度

本文详细介绍了Linux系统中的进程管理,包括进程描述符、进程切换、进程创建与终止,以及用户线程、内核线程和轻量级进程的区别。文章探讨了Linux线程模型,进程与线程的区别,并讲解了实时线程与实时操作系统的基本概念。最后,文章阐述了Linux的进程调度策略,包括抢占式调度和非抢占式调度的工作原理。
摘要由CSDN通过智能技术生成

目录

一、进程描述符     

二、进程切换

三、进程创建与终止

四、用户线程,内核线程和轻量级进程

 五、三种线程模型和Linux线程实现

六、进程与线程的区别

七、实时线程与实时操作系统

八、进程(线程)调度


一、进程描述符     

     进程描述符保存了与进程相关的一切信息,其数据类型为task_struct,Linux用双向链表和类似HashMap的散列表来保存所有的进程描述符,前者用于调度按照进程优先级快速选择一个可执行的进程,后者用于按照进程pid或者tgid快速查找一个进程或者进程组,给其发送信号等操作。进程描述符中包含很多的字段,重点关注一下几个:

(1) 、state字段

      表示进程的状态,共有6种:

      1、TASK_RUNNING,表示进程要么正在执行,要么准备执行,等待cpu时间片的调度

      2、TASK_INTERRUPTIBLE,表示进程被挂起(睡眠),直到某个条件成立触发CPU中断或者发送信号唤醒该进程,将其状态改成TASK_RUNNING,比如某个TASK_RUNNING的进程需要读取文件,发起系统调用从用户态进入内核态,内核将其状态改成TASK_INTERRUPTIBLE,然后调用磁盘驱动程序读取文件,CPU执行其他任务;待磁盘读取文件完毕,磁盘发送CPU中断信号,CPU将读取的文件内容传给进程,进程由内核态切换到用户态,处理文件内容。一般情况下,进程列表中的绝大多数进程都处于TASK_INTERRUPTIBLE状态,除非机器的负载很高。

      3、TASK_UNINTERRUPTIBLE,与TASK_INTERRUPTIBLE类似,区别是不能被外部信号唤醒,只能通过CPU中断唤醒。该状态总是非常短暂的,通过ps命令基本上不可能捕捉,主要用于避免内核某些处理过程被中断,如进程与设备交互的过程,中断会造成设备陷入不可控的状态。

     4、TASK_STOPPED,表示进程的执行已停止,向进程发送一个SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU信号,它就会因响应该信号而进入TASK_STOPPED状态,向进程发送一个向进程SIGCONT信号,可以让其恢复到TASK_RUNNING状态。

    5、TASK_TRACED,表示进程的执行已停止,等待跟踪它的进程对它进行操作,比如在gdb中对被跟踪的进程下一个断点,进程在断点处停下来的时候就处于TASK_TRACED状态。处于TASK_TRACED状态的进程不能响应SIGCONT信号而被唤醒,只能等到调试进程通过ptrace系统调用执行PTRACE_CONT、PTRACE_DETACH等操作或调试进程退出,被调试的进程才能恢复TASK_RUNNING状态。

    6、EXIT_ZOMBIE,表示进程已终止,正等待其父进程执行wait类系统调用收集关于它的一些统计信息如退出码,内核此时无法回收该进程的进程描述符。如果父进程未执行wait类系统调用并退出了,子进程会转交给上一级的父进程,直到最终的init进程,由上一级父进程执行wait类系统调用。

  7、EXIT_DEAD,表示进程已终止,父进程已经执行wait类系统调用,进程即将被内核删除,该状态非常短暂。

      Linux Kernel 2.6.25 引入了一种新的进程睡眠状态,TASK_KILLABLE:当进程处于这种可以终止的新睡眠状态中,它的运行原理类似于 TASK_UNINTERRUPTIBLE,只不过可以响应致命信号。     

(2)、pid和tgid字段

   pid标识一个唯一的进程,从0开始逐渐递增,到最大值后就开始利用空闲的未分配pid;tgid标识当前进程所属的进程组的id,在Linux系统中,该ID就是该进程组的领头进程(该组中的第一个轻量级进程)相同的PID。

(3)、stack字段

    该字段是一个指针变量,表示当前进程的thread_info的地址,thread_info和内核态堆栈紧挨着,存放在两个连续的页框中,通过thread_info中的进程描述符指针快速访问进程描述符,其结构如下图:

图中,esp寄存器用来存放栈顶单元的地址。在80x86系统中,栈起始于顶端,并朝着这个内存区开始的方向增长。从用户态刚切换到内核态以后,进程的内核栈总是空的。因此,esp寄存器指向这个栈的顶端。一旦数据写入堆栈,esp的值就递减。为了快速获取当前CPU上运行进程的task_struct结构,内核提供了current宏, 该宏就是通过esp寄存器保存的栈顶地址快速获取对应的task_struct。

(4)、mm和active_mm字段

       mm标识进程所拥有的用户空间内存描述符,内核线程无的mm为NULL;active_mm指向进程运行时所使用的内存描述符, 对于普通进程而言,这两个指针变量的值相同。但是内核线程kernel thread是没有进程地址空间的,所以内核线程的tsk->mm域是空(NULL)。但是内核线程需要访问内核空间,因为所有进程的内核空间都一样,所以它的active_mm成员被初始化为前一个运行进程的mm值,借此访问内核空间。

(5)、thread 字段

        该字段是一个指针变量,数据结构为thread_struct,用于进程切换时保存除通用寄存器以外的寄存器的内容,用于恢复进程执行上下文使用,跟CPU架构强相关。通用寄存器的内容保存在内核堆栈中。

     参考:Linux进程状态解析 之 R、S、D、T、Z、X (主要有三个状态)

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值