2009-12-12 42 views
7

我正在运行2个线程(假设他们现在是pthreads)。 Thread_1()进行用户定义的API调用,最终在内核中执行一些工作。 Thread_2()完全在用户空间中。线程可以在系统调用内核的时候被抢占吗?

我的问题是:当API调用正在进行时,Thread_2()是否可以通过抢占Thread_1()来执行,控件是否在内核中的某处?如果不是,为什么,如果我想要发生这种情况(出于任何原因),我该怎么做?

回答

5

如果您在询问是否需要磁盘IO的阻塞内核调用像fread()可以被抢占,那么是的。

更具体地说,阻塞调用基本上会让Thread_1在等待它所等待的任何事情时进入休眠状态。如果Thread_1处于睡眠状态,则Thread_2将计划运行(除非有更高的优先级等待运行)。

编辑:如果你想办法是“相当有信心”是Thread_1正在执行阻塞调用,使Thread_2优先级低于Thread_1(这样一般运行,除非Thread_1被阻止)和当它运行时,它会将其优先级提升到比Thread_1更高的级别,直到硬件中断已交付,此时它降低其优先级并调用sched_yield()

+0

其实这假设你的线程是内核管理的。而一些内核可能会有所不同。 – Artelius

+0

您能否澄清一下 - 内核管理与非内核管理之间的区别?存在哪些变化? – TCSGrad

+0

内核管理的线程被内核视为单个进程。内部进程(无内核支持)调度其各个线程。通常,如果其中一个线程阻塞,则整个进程被内核阻塞,因此没有线程运行。如果线程是内核管理的,如果一个线程阻塞,大​​多数内核将运行其他线程。您可以运行一个简单的测试,其中一个线程反复调用系统调用,另一个线程重复收益。如果yielding线程获得任何运行时间,则意味着系统调用是抢占点。 – Artelius

8

调用内核被认为是阻塞非阻塞。阻塞调用(例如等待数据从网络套接字中读取)当然可以被抢占,而不需要您执行任何操作。其他线程将继续运行。非阻塞内核调用可以被认为是非常快速的,并且实际上,如果你真的可以抢占它们,它并不重要。

一般来说,在编写多线程代码时,您将重点关注这些线程如何相互交互,并将它们与内核的交互直至内核进行管理。它旨在做一个很好的工作。

+0

那么,在这种情况下,我正在编写一个API测试,测试计划包括分析HW中断(在用户空间时可以从Thread_2()启动) API的执行。因此,理想情况下,我希望Thread_1(_能够在API的执行过程中产生效果,将控制权交给Thread_2()(开始导致硬件中断的序列),然后返回到Thread_1()并恢复执行 - 如果API可以保存其自己的/保存状态等,而硬件中断实际上击中它,那么一切都很好! – TCSGrad

+0

你可能想看到我在这个http://stackoverflow.com/思考的替代方法问题/ 1885903 /如何调用交流功能,从随机位置到另一个功能。你可以跳过它 - 所有的信息都在这里这个问题!:) – TCSGrad

7

这取决于内核。经典的内核不允许抢占(除了在特定的时刻睡眠线程时)。但是更新的内核已经开始在内核中启用抢占。

当使用CONFIG_PREEMPT构建Linux时,Linux支持可抢占内核。从内核文件:

此选项可减少内核的通过使 所有内核代码的潜伏期(未在临界区执行) 抢占。这允许对 的交互事件作出反应,允许不自愿地优先处理低优先级进程 ,即使它处于内核模式下执行系统调用,并且在其他情况下不会达到自然抢占点。 即使系统处于负载下,这也允许应用程序运行更“平稳”,但代价是吞吐量略低, 以及内核代码的运行时开销较小。

如果您正在为台式机或 嵌入式系统构建内核,请选择此项,延迟要求在毫秒 范围内。