主要内容

进程

进程描述符及任务结构

进程创建

线程在linux中的实现

进程终结

1. 进程

进程不仅仅是一段可执行程序代码,还包含其他资源,如打开的文件,挂起的信号,内核内部数据,处理器状态,一个或多个具有内存映射的内存地址空间及一个或多个执行线程,存放全局变量的数据段等等。具体可见进程的地址空间。

线程是进程中活动的对象,拥有独立的PC程序计数器,进程栈和一组进程寄存器,是内核调度的基本对象。

进程的两种虚拟机制:虚拟处理器和虚拟内存

相关函数:

fork(),系统调用从内核返回两次,一次回到父进程,一次回到新产生的子进程

exec(),创建新的地址空间并载入程序

exit() 退出执行

wait() , waitpid(),父进程等待子进程终结

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

双向链表的任务队列

分配进程描述符

linux通过slab分配器分配task_struct结构,通过预先分配和重复使用,可以避免动态分配和释放带来的资源消耗。

在进程的内核栈中,每个任务的thread_info结构在它内核栈的尾端分配,结构中task域存放的是指向该任务实际task_struct的指针。

进程描述符的存放

pid,最大值默认为short int的最大值32768,可以修改pid_max文件来提高上限

进程状态

进程状态转化.png

TASK_RUNNING,运行——进程或者正在执行,或者在运行队列中等待执行

TASK_INTERRUPTIBLE,可中断——进程正在睡眠(被阻塞),等待某些条件的达成

TASK_UNINTERRUPTIBLE,不可中断

_TASK_TRACED,被其它进程跟踪的进程

_TASK_STOPPED,进程停止执行,如接收到SIGSTOP,SIGTINT等信号

设置当前进程状态

set_task_state(task, state)

进程上下文

当一个程序执行了系统调用或者触发了某个异常,它就陷入了内核空间,此时,我们呈内核“代表进程执行”并处于进程上下文中

进程家族树

Unix系统的进程之间存在一个明显的集成关系,所有进程都是PID为1的init进程的后代

进程关系:父子,兄弟,在进程描述符中存放,每个task_struct都有指向父进程、子进程的指针

3. 进程创建

linux中创建进程分两步,fork和exec

linux的fork()使用写时拷贝(copy-on-write)实现,因为有可能fork后是执行一个新的映像,父进程和子进程共享同一份拷贝,只有在需要写入的时候,才会被复制。因此,fork()的实际开销就是复制父进程的页表以及给子进程创建唯一的进程描述符

linux通过clone()系统调用do_fork(),do_fork()调用copy_process()函数,然后让进程开始运行,copy_process()完成的工作如下:

调用dup_task_struct()为新进程分配内核栈,task_struct等,其中的值与当前进程相同,此时,子进程与父进程的描述符也相同

检查创建子进程后,当前用户所拥有的进程数目没有超出给它分配的资源限制

子进程使自己与父进程区别开来。进程描述符内许多统计信息成员都要被清0或设为初始值

子进程状态设置为TASK_UNINTERRUPTIBLE,以保证不会投入运行

更新task_struct的flags成员,表明进程权限等

调用alloc_pid()为新进程分配一个有效的PID

根据传递给clone()的参数,copy_process()拷贝或共享打开的文件,文件系统信息,信号处理函数,进程地址空间和命名空间等

扫尾工作,返回指向子进程的指针

回到do_fork()函数后,内核会优先选择子进程首先执行,因为子进程通常会马上调用exec()函数,可以避免写时拷贝的额外开销。

创建进程的fork()函数实际上最终是调用clone()函数。

vfork()调用,不拷贝父进程的页表项,子进程作为父进程的一个单独的线程在它的地址空间里运行,父进程被阻塞直到子进程退出或执行exec(),子进程不能向地址空间写入。

现在for()引入了写时拷贝并且明确了子进程先执行,vfork()的好处就仅限于不执行父进程的页表项了。

而且如果exec()调用失败会怎样?

4. 线程在Linux中的实现

从内核的角度来说,并没有线程这个概念,Linux把所有的线程都当做进程来实现,线程仅仅被视为一个与其他进程共享某些资源的进程。

Windows在内核中提供了专门支持线程的机制。而对Linux来说,只是一种进程间共享资源的手段。

线程的创建和普通进程的创建类似,只不过调用clone()的时候需要传递额外参数标识

一个普通的fork():clone(SIGCHLD, 0)

创建线程:clone(CLONE_VFORK | CLONE_VM | SIGCHLD, 0) 使子进程和父进程共享地址空间,文件资源,文件描述符,信号处理程序等。

内核线程:

内核线程没有独立的地址空间,只在内核空间运行,可以被调度或抢占

5. 进程终结

当一个进程终结时,内核必须释放它所占有的资源并告知父进程

终结任务依靠do_exit()来完成:

设置task_struct中的标识成员设置为PF_EXITING

调用del_timer_sync()删除内核定时器, 确保没有定时器在排队和运行

调用exit_mm()释放进程占用的mm_struct

调用sem__exit(),使进程离开等待IPC信号的队列

调用exit_files()和exit_fs(),释放进程占用的文件描述符和文件系统资源

把存放在task_struct的exit_code成员中的任务退出代码置为exit()提供的退出代码,或者去完成任何其他由内核机制规定的退出动作,退出代码存放在此供父进程随时检索

调用exit_notify()向父进程发送信号,给子进程重新找养父(init进程),并把进程状态设为EXIT_ZOMBIE

do_exit()调用schedule()切换到新的进程,不会再被调度,do_exit()永不返回

至此,与进程相关联的所有资源都被释放掉了,进程处于(EXIT_ZONBIE退出状态)且不可运行,占用的内存仅剩内核栈、thread_info结构和tast_struct结构,此时进程存在的唯一目的就是向它的父进程提供信息。父进程检索到信息后,由进程所持有的剩余内存被释放,归还给系统。

wait()通过系统调用wait4()来实现,返回子进程的PID,调用该函数时提供的指针会包含子函数退出时的退出代码

删除进程描述符,父进程调用release_task()

如果没有父进程,子进程exit_notify()的时候,调用forget_original_parent() -> find_new_reaper()来执行寻父过程

linux内核的进程管理,Linux内核设计与实现——进程管理相关推荐

  1. Linux进程内消息总线设计

    文章目录 Windows平台进程内消息总线 如果没有消息总线,会产生什么问题 死循环包含关系 高耦合.低内聚 消息总线 结构图 原理 生产者与总线的关系 总线与消费者的关系 Linux进程内消息总线设 ...

  2. 管理类软件设计“渔”之演化

    中国软件行业发展了这么多年,管理类软件的设计主线上大致经历了三大阶段. 第一代"管钱.物"为主: 大家都知道,中国第一代管理类软件主要是以"管钱.物"为主的各类 ...

  3. linux内核设计与实现---进程管理

    进程管理 1 进程描述符及任务结构 分配进程描述符 进程描述符的存放 进程状态 设置当前进程状态 进程上下文 进程家族树 2 进程创建 写时拷贝 fork() vfork() 3 线程在Linux中的 ...

  4. 【Linux 内核】进程管理 ( Linux 内核中的进程状态 | TASK_RUNNING | TASK_INTERRUPTIBLE | __TASK_STOPPED | EXIT_ZOMBIE )

    文章目录 一.Linux 内核中的进程状态 二.TASK_RUNNING 状态 三.TASK_RUNNING 状态 四.TASK_UNINTERRUPTIBLE 状态 五.__TASK_STOPPED ...

  5. linux kernel 进程管理,Linux内核 | 进程管理

    1. 进程和线程 1.1 定义 进程是处于运行状态的程序和相关资源的总称,是资源分配的最小单位. 线程是进程的内部的一个执行序列,是CPU调度的最小单位.有一段可执行程序代码. 有一段进程专用的系统堆 ...

  6. Linux进程管理:内核中的优先级继承互斥(rtmutex.h):防止优先级反转

    目录 Priority inheritance in the kernel 译文 Priority inheritance in the kernel https://lwn.net/Articles ...

  7. 红黑树在linux内核中的应用场景(红黑树,进程管理CFS,内存管理)丨epoll丨c/c++linux服务器开发丨linux后台开发

    红黑树在linux内核中的应用场景(红黑树,进程管理CFS,内存管理) 视频讲解如下: 红黑树在linux内核中的应用场景(红黑树,进程管理CFS,内存管理)丨epoll丨c/c++linux服务器开 ...

  8. 【Linux 内核】进程管理 ( 进程特殊形式 | 内核线程 | 用户线程 | C 标准库与 Linux 内核中进程相关概念 | Linux 查看进程命令及输出字段解析 )

    文章目录 一.进程特殊形式 ( 内核线程 | 用户线程 ) 二.C 标准库与 Linux 内核中进程相关概念 三.Linux 查看进程命令及输出字段解析 一.进程特殊形式 ( 内核线程 | 用户线程 ...

  9. 【Linux 内核】进程管理 ( Linux 中进程的 CPU 资源调度 | 进程生命周期 | 创建状态 | 就绪状态 | 执行状态 | 阻塞状态 | 终止状态 | 进程生命周期之间的转换 )

    文章目录 一.Linux 中进程的 CPU 资源调度 二.进程生命周期 三.进程生命周期之间的转换 一.Linux 中进程的 CPU 资源调度 Linux 操作系统 是 多任务系统 , 可以 同时运行 ...

最新文章

  1. java 文件压缩 解压_Java文件压缩与解压缩(一)
  2. 三个Javascript内容切换效果类
  3. javacurrentmap_Java 8 并发: 原子变量和 ConcurrentMap
  4. swapCursor vs changeCursor, what’s the difference?
  5. PK3Err0040: The target device is not ready for debugging. Please check your configuration bit settin
  6. nodeMCU自动化控制实现空气质量管家
  7. 汇编语言(二十)之分类统计字符个数
  8. 面试被问项目上线没_面试官的最爱问“分布式”核心设计问题,没掌握的不妨来看看...
  9. 最新电脑为什么用ghost无法安装系统?安装版正常,是何原因?
  10. 腾讯云VP王龙:与英特尔的合作将加速AI落地,硬件的灵活性要变得更强
  11. dos从优盘启动计算机,对老旧电脑升级很重要,教你制作纯DOS的U盘启动盘
  12. 柳州铁一中机器人_柳州铁一中学学子在2020年广西中小学电脑机器人竞赛中勇创佳绩...
  13. “极地测绘之父”鄂栋臣逝世,曾签下生死状首征南极
  14. iphone html 手机震动,iPhone来电不会震动怎么回事?简单几招排查技巧
  15. Linux下部署worldPress
  16. 用Python写个「倒计时」软件
  17. RISC-V为中国MCU企业打开一个新窗口!
  18. 坤音键盘(ikun专用)
  19. 如何在阿里云购买物联网卡并激活
  20. Linux操作系统中网络配置命令

热门文章

  1. Django 验证码4.4
  2. 电商商品模块数据设计与关系图
  3. java 多线程 事件_java 多线程-线程不安全案例
  4. TypeError: can only concatenate str (not “float“) to str
  5. Android 使用adb 命令截图 的方法
  6. Java 打印数组的方法
  7. Android onAttach 的使用
  8. Linux磁盘空间满的处理方法
  9. VLOG丨树莓派Raspberry Pi 3安装PLEX并挂载USB硬盘打造最牛的微型家庭影音服务器2018...
  10. NuGet学习笔记(1) 初识NuGet及快速安装使用