首先,templatetypedef的答案很漂亮;我只是想稍微扩展他的回答。
我觉得有一个领域需要扩展一点:ULT 和 KLT 的组合。要了解重要性(维基百科标记混合线程),请考虑以下示例:
考虑一个多线程程序(多个 KLT),其中 KLT 多于可用逻辑内核。为了有效地使用每个内核,正如您所提到的,您希望调度程序将阻塞的 KLT 切换到处于就绪状态且未阻塞的 KLT。这可确保核心减少其空闲时间。不幸的是,切换 KLT 对调度程序来说代价高昂,并且会消耗相对大量的 CPU 时间。
这是混合线程可以提供帮助的一个领域。考虑一个具有多个 KLT 和 ULT 的多线程程序。正如templatetypedef所指出的,每个 KLT 一次只能运行一个 ULT。如果 ULT 被阻塞,我们仍然希望将其切换为没有阻塞的 ULT。幸运的是,ULT 比 KLT 轻得多,因为分配给 ULT 的资源更少,并且它们不需要与内核调度程序交互。从本质上讲,切换 ULT 几乎总是比切换 KLT 更快。因此,相对于第一个示例,我们能够显着减少核心空闲时间。
现在,当然,所有这些都取决于用于实现 ULT 的线程库。有两种方法(我可以想出)将 ULT 映射到 KLT。
所有KLT 的ULT 集合
这种情况在共享内存系统上是理想的。本质上,每个 KLT 都可以访问 ULT 的“池”。理想情况下,线程库调度程序将根据请求将 ULT 分配给每个 KLT,而不是 KLT 单独访问池。如果不使用锁或类似的东西实现,后者可能会导致竞争条件或死锁。
每个KLT的 ULT 集合( Qthreads)
这种情况在分布式内存系统上是理想的。每个 KLT 都会有一组 ULT 来运行。缺点是用户(或线程库)必须在 KLT 之间划分 ULT。这可能会导致负载不平衡,因为不能保证所有 ULT 将完成相同数量的工作,并且完成大致相同的时间。解决方案是允许 ULT 迁移;也就是说,在 KLT 之间迁移 ULT。