kernel启动过程的三个特殊进程


  • Linux下有3个特殊的进程,分别是idle进程、init进程、kthreadd进程

idle进程

  1. [linux]进程(三)——idle进程
  2. Linux下0号进程的前世(init_task进程)今生(idle进程)—-Linux进程的管理与调度(五)
  • idle进程(PID = 0):其前身为init_task进程,该由系统自动创建, 运行在内核态,是系统创建的第一个进程,也是唯一一个没有通过fork或者kernel_thread产生的进程。完成加载系统后,先后创建kernel_init(该进程最终演变为init进程)和kthreadd进程,并最终演变为idle进程
  • idle进程的作用:idle进程不参与进程调度机制,当系统中没有任何进程可以调度(就绪队列为空)时,cpu就会进入该进程 —— 也就是说当系统没事干的时候就执行它,其存在的目的是为了让调度器一直处于运行状态(要不然所有的进程全挂起了调度器就会空闲下来)。

    系统的空闲时间,其实就是指idle进程的”运行时间”

  • 在多核系统中,每个处理器单元都有独立的一个运行队列,而每个运行队列上又有一个idle进程 —— 因此有多少cpu,就有多少idle进程。

idle进程的演化

  1. Linux在无进程概念的情况下从初始化部分的代码一直执行到调用start_kernel()函数为止,接着创建原始进程init_task(即0号线程)。

    • 原始进程:虽然进程号为0,但此时还不叫idle进程,而叫init_task进程
  2. 原始进程init_task开始执行start_kernel()完成Linux内核的初始化工作(包括初始化页表,初始化中断向量表,初始化系统时间等),直到执行到start_kernel()中的最后一个函数rest_init()

  3. 原始进程init_task在rest_init()中开始产生其它进程(即init进程和kthreadd进程),并最终退化为idle进程。

    • rest_init()函数的内容

      static noinline void __init_refok rest_init(void) {
          ...
          kernel_thread(kernel_init, NULL, CLONE_FS); // 创建kernel_init进程(即1号进程),该进程最终演化为init进程
          ...
          pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);   // 创建kthreadd进程(即2号进程),该进程负责所有内核线程的调度和管理
          ...
          init_idle_bootup_task(current); // 将原始进程隶属到idle调度类中
          schedule_preempt_disabled();    // 使1号进程kernel_init处于运行状态
          cpu_startup_entry(CPUHP_ONLINE);    // 使得0号进程进入idle事件循环 —— 即最终演变为idle进程
      }
    • rest_init()函数的执行步骤

      1. 调用kernel_thread()创建1号内核进程kernel_init, 该进程随后转向用户空间, 并最终演变为init进程。
      2. 调用kernel_thread()创建kthreadd内核进程,该进程一直在内核中,并最终演变为kthreadd进程。
      3. 调用init_idle_bootup_task()将原始进程隶属到idle调度类中。
      4. 调用schedule_preempt_disabled()切换当前进程,使1号进程kernel_init处于运行状态
      5. 调用cpu_startup_entry(),而该函数又会间接调用cpu_idle_loop(),使得0号进程进入idle事件循环 —— 即最终演变为idle进程

init进程

  1. Linux下1号进程的前世(kernel_init)今生(init进程)—-Linux进程的管理与调度(六)
  • init进程(PID = 1)由idle通过kernel_thread创建(此时还不是init进程,而是kernel_init进程,运行在内核空间),在内核空间完成初始化后,加载init程序(该init程序会替换kernel_init进程,使得内核空间的kernel_init进程最终转换为用户空间内的1号进程init)。 该进程是系统中所有其它用户进程的祖先进程(Linux中的所有用户进程都是有init进程创建并运行的),在系统启动完成完成后,最终变为守护进程监视系统其他进程

kthreadd进程

  1. Linux下2号进程的kthreadd–Linux进程的管理与调度(七)
  • kthreadd(PID = 2)由idle通过kernel_thread创建,并始终运行在内核空间, 负责所有内核线程的调度和管理(它的任务就是管理和调度其他内核线程kernel_thread, 会循环执行一个kthread的函数,该函数的作用就是运行kthread_create_list全局链表中维护的kthread, 当我们调用kernel_thread创建的内核线程会被加入到此链表中,因此所有的内核线程都是直接或者间接的以kthreadd为父进程 

http://blog.leanote.com/post/804305986@qq.com/e8672f7c86e9
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值