【问题标题】:How the scheduling or preemption of Linux kernel thread works?Linux内核线程的调度或抢占如何工作?
【发布时间】:2014-01-29 17:31:13
【问题描述】:

据我所知,与用户空间线程/进程相比,Linux 内核线程没有自己的地址空间。内核线程不会上下文切换到用户空间,但内核线程是可调度和可抢占的。所以我的问题是,如果内核线程没有地址空间,那么内核线程的切换/抢占如何工作?

【问题讨论】:

  • 是什么让您认为它需要用户空间地址空间才能使进程/线程可抢占?
  • 我并不是说它需要用户地址空间,我的疑问是如果内核线程没有地址空间,那么它将如何访问内核代码/指令?
  • 一个内核线程,在内核上下文和地址空间中运行!内核线程可能是可抢占的(CONFIG 选项),在这种情况下,中断会导致调度程序重新评估并切换到另一个线程。如果内核不是抢占式的,那么线程会一直运行,直到完成,协作多任务;在内核中作为内核代码工作的是trusted

标签: linux multithreading kernel scheduling preemption


【解决方案1】:

内核线程基本上执行一个函数。它们是使用kernel_thread() 函数创建的,该函数接收要执行的函数的地址、该函数的参数和一些克隆标志作为参数。

这个函数本质上调用了一个通用的do_fork(),将内核模式堆栈的地址传递给它,copy_thread() 将在其中找到内核线程的 CPU 寄存器的初始值。

基本上kernel_thread() 以以下方式构建堆栈:

  • ebxedx 寄存器将由 copy_thread() 设置为值 fnarg
  • eip 将设置为一个小例程,它将加载参数和 call fn

这样新的内核线程开始执行fn(arg)

如您所见,内核线程通过fn 的地址知道要执行什么代码。这个函数通常已经在内核内部的某个地方定义了,通过设置eip 指向那里,这样内核线程就知道要执行的指令。不需要text segment,因为不需要将可执行文件映射到内存区域。

【讨论】:

  • 如果内核线程正在执行函数(其中的地址被传递给内核线程)并且在函数完成之前内核线程被抢占,那么它将如何再次重新调度?
  • 当它被抢占时,eip(在所有其他寄存器中)存储在内核模式堆栈或current.thread strcut。一旦恢复,所有这些寄存器都被设置回来,所以下一条指令将是eip。我自己解释一下吗?
  • 看来你已经解决了我的疑问。谢谢 Paulo Bu。
猜你喜欢
  • 1970-01-01
  • 2018-09-16
  • 1970-01-01
  • 2012-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多