进程管理

1.进程描述符及任务结构

进程存放在叫做任务队列(task list)的双向循环链表中。链表中的每一项包含一个具体进程的所有信息,类型为task_struct,称为进程描述符(process descriptor),该结构定义在<linux/sched.h>文件中。

Linux通过slab分配器分配task_struct结构,这样能达到对象复用和缓存着色(cache coloring)的目的。另一方面,为了避免使用额外的寄存器存储专门记录,让像x86这样寄存器较少的硬件体系结构只要通过栈指针就能计算出task_struct的位置,该结构为thread_info,在文件<asm/thread_info.h>中定义。

2.进程状态

task_struct中的state描述进程的当前状态。进程的状态一共有5种,而进程必然处于其中一种状态:

1)TASK_RUNNING(运行)——进程是可执行的,它或者正在执行,或者在运行队列中等待执行。这是进程在用户空间中执行唯一可能的状态;也可以应用到内核空间中正在执行的进程。

2)TASK_INTERRUPTIBLE(可中断)——进程正在睡眠(也就是说它被阻塞)等待某些条件的达成。一旦这些条件达成,内核就会把进程状态设置为运行,处于此状态的进程也会因为接收到信号而提前被唤醒并投入运行。

3)TASK_UNINTERRUPTIBLE(不可中断)——除了不会因为接收到信号而被唤醒从而投入运行外,这个状态与可打断状态相同。这个状态通常在进程必须在等待时不受干扰或等待事件很快就会发生时出现。由于处于此状态的任务对信号不作响应,所以较之可中断状态,使用得较少。

4)TASK_ZOMBIE(僵死)——该进程已经结束了,但是其父进程还没有调用wait4()系统调用。为了父进程能够获知它的消息,子进程的进程描述符仍然被保留着。一旦父进程调用了wait4(),进程描述符就会被释放。

5)TASK_STOPPED(停止)——进程停止执行,进程没有投入运行也不能投入运行。通常这种状态发生在接收到SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU等信号的时候。此外,在调试期间接收到任何信号,都会使进程进入这种状态。

需要调整进程的状态,最好使用set_task_state(task, state)函数,在必要的时候,它会设置内存屏障来强制其他处理器作重新排序(SMP)。

3.进程创建

在Linux系统中,所有的进程都是PID为1的init进程的后代。内核在系统启动的最后阶段启动init进程。该进程读取系统的初始化脚本(initscript)并执行其他的相关程序,最终完成系统启动的整个进程。

Linux提供两个函数去处理进程的创建和执行:fork()和exec()。首先,fork()通过拷贝当前进程创建一个子进程。子进程与父进程的区别仅仅在于PID(每个进程唯一),PPID(父进程的PID)和某些资源和统计量(例如挂起的信号)。exec()函数负责读取可执行文件并将其载入地址空间开始运行。

fork()使用写时拷贝(copy-on-write)页实现。内核在fork进程时不复制整个进程地址空间,让父进程和子进程共享同一个拷贝,当需要写入时,数据才会被复制,使各进程拥有自己的拷贝。在页根本不会被写入的情况下(fork()后立即exec()),fork的实际开销只有复制父进程的页表以及给子进程创建唯一的task_struct。

4.线程的实现

从Linux内核的角度来说,它并没有线程这个概念。Linux把所有的线程都当作进程来实现,内核并没有准备特别的调度算法或者定义特别的数据结构来表征线程。相反,每个线程都拥有唯一隶属于自己的task_struct,它看起来就像是一个普通的进程,只是该进程和其他一些进程共享某些资源,如地址空间。

5.进程终结

进程在运行结束,或接受到它既不能处理也不能忽略的信号,或异常时,都会被终结。此时,依靠do_exit()(在kernel/exit.c文件中)把与进程相关联的所有资源都被释放掉(假设进程是这些资源的唯一使用者)。进程不可运行(实际上也没有地址空间让它运行)并处于TASK_ZOMBIE状态。它占用的所有资源就是内核栈、thread_info和task_struct。在父进程获得已终结的子进程的信息后,或者通知内核它并不关注那些信息后,子进程的task_struct才被释放。

如果父进程在子进程之前退出,必须有机制保证子进程能找到一个新的父类,否则的话这些成为孤儿的进程就会在退出时永远处于僵死状态,白白的耗费内存。解决方法是给子进程在当前线程组内找一个线程作为父亲,如果不行,就让init做它们的父进程。

转载于:https://www.cnblogs.com/pennant/archive/2012/12/15/2817439.html

《Linux内核设计与实现》读书笔记(2)--- 进程管理相关推荐

  1. linux内核设计与实现看不懂,Linux内核设计与实现读书笔记

    Unix强大的根本原因: Unix简洁, 提供几百个系统调用, 设计目的明确 Unix中 所有东西都被当做文件对待 Unix内核和相关系统工具是用C语言开发的, 移植能力强大 Unix进程创建迅速, ...

  2. Linux内核设计与实现 读书笔记

    第二章 Linux内核 1 内核开发特点 1)内核编译时不能访问C库: 2)浮点数很难使用: 3)内核只有一个定长堆栈: 4)注意同步和并发. 第三章 进程管理 1 current宏:查找当前运行进程 ...

  3. Linux内核设计与实现读书笔记

    1.进程管理 内核通过task_struct管理进程. 2.进程调度 1.可执行队列runqueue. 2.用户抢占.从中断返回或者系统调用返回的时候发生. 3.系统调用 1.系统调用参数放在寄存器里 ...

  4. 进程调度(一)--linux内核设计与实现读书笔记

    进程的调度程序是保证进程能有效工作的一个内核子系统.调度程序负责决定将哪个进程投入运行,何时运行以及运行多少时间.简单的来说,调度程序就是在给一堆就绪的进程分配处理器的时间,调度程序是多任务操作系统的 ...

  5. linux+模块与设备关系,linux内核设计与实现读书笔记——设备和模块

    一.设备类型 1.块设备 blkdev:以块为单位寻址,支持重定位(数据随机访问),通过块设备节点来访问. 2.字符设备cdev:不可寻址,提供数据流访问,通过字符设备节点访问. 3.网络设备:对网络 ...

  6. Linux内核设计与实现学习笔记目录

    **注:**这是别人的笔记,我只是把目录抄过来 <Linux内核设计与实现学习笔记> 1.<Linux内核设计与实现>读书笔记(一)-内核简介 2.<Linux内核设计与 ...

  7. 初探内核之《Linux内核设计与实现》笔记上

    内核简介  本篇简单介绍内核相关的基本概念. 主要内容: 单内核和微内核 内核版本号 1. 单内核和微内核   原理 优势 劣势 单内核 整个内核都在一个大内核地址空间上运行. 1. 简单. 2. 高 ...

  8. linux内核双向循环队列,读书笔记之linux内核设计与实现(2)进程调度

    调度程序是内核的组成部分,它负责选择下一个要运行的进程.进程调度程序可看作在可运行态进程之间分配有限的处理器时间资源的内核子系统. 多任务操作系统就是能够同时并发的交互执行多个进程的操作系统.多任务系 ...

  9. Linux内核设计与实现 总结笔记(第五章)系统调用

    系统调用 内核提供了用户进程和内核交互的接口,使得应用程序可以受限制的访问硬件设备. 提供这些接口主要是为了保证系统稳定可靠,避免应用程序恣意妄行. 一.内核通信 系统调用在用户空间进程和硬件设备之间 ...

最新文章

  1. 【Java】时间复杂度 与 空间复杂度
  2. UML从需求到实现---类图(2)
  3. Linux命令集合(更新中。。。)
  4. Git简介及其下载 安装 卸载
  5. mysql 4.0.21 下载_W2K下安装 MYSQL 4.0.21 手记
  6. Java 403 forbidden错误解决
  7. JAVA基础系列:Object类
  8. OpenCV-高斯低通高通滤波器(C++)
  9. [渝粤教育] 广东-国家-开放大学 21秋期末考试物权法10774k1
  10. case结构条件语句
  11. 【第158期】游戏策划:给@zhang的简历分析
  12. 通过倍福Twincat的R3IO添加外部C++程序
  13. Linux命令 - /etc/passwd文件详解
  14. WIN10防火墙端口添加例外
  15. python视觉识别线条_简单车道线识别
  16. linux红帽修改默认字体大小,为 Redhat Linux 添加新字体
  17. V2V迁移测试--VMware/VSphere环境迁移至KVM
  18. 再听 ,抖音视频背景制作---小龙老师
  19. Linux 主机网络接入配置
  20. 《把时间当作朋友》第1章读后感(二)

热门文章

  1. 基于python的图像分割并计数
  2. java ognl表达式 与struts2标签_Struts2 OGNL表达式实例详解
  3. Java 解析Excel(xls、xlsx两种格式)
  4. Springboot @Transactional Mysql事务 无效
  5. fixed与sticky的区别
  6. java中native的用法
  7. django 笔记17 ModelForm
  8. MySQL错误ERROR 1366 (HY000): Incorrect string value..
  9. LiveCoding
  10. 微信生态圈盈­利模式分析