对于用户级线程,在单个内核线程上运行N个用户级线程。这与只有一个用户线程在内核线程上运行的pthread相反。如何在Linux中为用户级线程实施抢先式调度?
在单个内核线程上抢先调度N个用户级线程。但是,这是如何做的细节。
我听到一些建议线程库设置的东西,以便内核发送信号,这是将执行从单个用户级线程抽出到信号处理程序的机制,然后可以执行抢先调度。
但是,如何保存和/或突变状态(如寄存器和线程结构)以使这一切工作的细节如何?是否有一个非常简单的用户级线程可用于了解详细信息?
对于用户级线程,在单个内核线程上运行N个用户级线程。这与只有一个用户线程在内核线程上运行的pthread相反。如何在Linux中为用户级线程实施抢先式调度?
在单个内核线程上抢先调度N个用户级线程。但是,这是如何做的细节。
我听到一些建议线程库设置的东西,以便内核发送信号,这是将执行从单个用户级线程抽出到信号处理程序的机制,然后可以执行抢先调度。
但是,如何保存和/或突变状态(如寄存器和线程结构)以使这一切工作的细节如何?是否有一个非常简单的用户级线程可用于了解详细信息?
要获得详细信息,请使用源代码!但这是我读到它时记得的......
用户级别的线程有两种调度方式:自愿和抢先。
yield()
或schedule()
或类似的东西。SIGALARM
(详情请参见man ualarm
)。关于如何做到真正的开关,如果你的操作系统是友好的,并提供必要的功能,那很容易。在Linux中,您可以使用makecontext()
/swapcontext()
函数轻松地从一个任务交换到另一个任务。再次请参阅手册页以获取详细信息。
不幸的是,这些函数从POSIX中删除,所以其他UNIX可能没有它们。如果是这样的话,还有其他的技巧可以完成。最流行的是一个调用sigaltstack()
来设置一个用于管理信号的备用堆栈,然后kill()
本身进入备用堆栈,longjmp()
从信号功能到您想要运行的实际用户模式线程。聪明,呃?作为一个侧面说明,在Windows中,用户模式线程被称为光纤并且也受到完全支持(请参阅文档CreateFiber()
)。
最后的手段是使用汇编程序,它可以在几乎任何地方工作,但它完全是系统特定的。创建UMT的步骤为:
并切换从一个UMT到另一个:
这些步骤在汇编程序中相对容易实现,但在普通C语言中完全不可能,没有上述任何技巧的支持。