在系统调用内核时是否可以抢占线程?

我正在运行2个线程(假设它们暂时是pthreads)。 Thread_1()进行用户定义的API调用,最终在内核中完成一些工作。 Thread_2()完全在用户空间中。

我的问题是:在API调用正在进行时,Thread_2()可以通过抢占Thread_1()来开始执行,控件是在内核中的某个地方吗? 如果不是,为什么,如果我希望这种情况发生(出于任何原因),我该怎么办?

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

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

编辑:如果你想要一种方法“相当自信”Thread_1正在执行阻塞调用,那么使Thread_2的优先级低于Thread_1(因此除非Thread_1被阻止,否则它通常不会运行)并且当它运行时,它会提升其优先级直到硬件中断被传递到更高级别而不是Thread_1,此时它会降低其优先级并调用sched_yield()

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

通常,在编写multithreading代码时,您要专注于这些线程如何相互交互,并将它们与内核的交互留给内核进行管理。 它旨在做得很好。

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

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

此选项通过使所有内核代码(不在临界区中执行)可抢占来减少内核的延迟。 这允许通过允许低优先级进程被非自愿地抢占来反应交互事件,即使它处于执行系统调用的内核模式中,否则将不会达到自然抢占点。 这样,即使系统处于负载状态,应用程序也可以更“平稳”运行,但代价是吞吐量略低,内核代码的运行时开销略有增加。

如果要为具有毫秒范围的延迟要求的桌面或嵌入式系统构建内核,请选择此选项。