什么是线程(用户/内核)?
线程是“轻量级进程”(LWPs)。其理念是,一个进程有五个基本组成部分:代码(“文本”)、数据(VM)、堆栈、文件 I/O 和信号表。“重量级进程”(HWPs)在切换时有大量的开销:每次任务切换时,所有表都必须从处理器中刷新。此外,在 HWPs 之间实现信息共享的唯一方法是通过管道和“共享内存”。如果 HWP 使用 fork() 派生子 HWP,则唯一共享的部分是文本。
线程通过共享基本组成部分来减少开销。通过共享这些部分,切换发生得更加频繁和高效。此外,共享信息不再那么“困难”:一切都可以共享。线程有两种类型:用户空间和内核空间。
用户空间避免内核并自行管理表。这通常被称为“协作式多任务处理”,其中任务定义了一组通过操作堆栈指针来“切换到”的例程。通常,每个线程通过调用显式切换、发送信号或执行涉及切换器的操作来“放弃”CPU。此外,定时器信号可以强制切换。用户线程通常可以比内核线程切换得更快[然而,Linux 内核线程的切换实际上性能非常接近]。
缺点。用户空间线程存在一个问题,即单个线程可能会垄断时间片,从而使任务中的其他线程饥饿。此外,它无法利用 SMP(对称多处理器系统,例如双核/四核奔腾)。最后,当一个线程变为 I/O 阻塞时,任务中的所有其他线程也会失去时间片。
解决方案/变通方法。一些用户线程库已通过几种变通方法解决了这些问题。首先,时间片垄断可以通过使用自身时钟节拍的外部监视器来控制。其次,一些 SMP 可以通过在指定的 CPU 上启动任务,然后从那里启动线程来支持用户空间多线程[这种形式的 SMP 线程充其量似乎很脆弱]。第三,一些库通过系统调用的特殊包装器解决了 I/O 阻塞问题,或者可以为非阻塞 I/O 编写任务。
内核空间线程通常在内核中使用多个表来实现(每个任务获取一个线程表)。在这种情况下,内核在每个进程的时间片内调度每个线程。从用户->内核->用户模式切换和加载更大的上下文会带来稍微多一点的开销,但初步的性能测量表明时间增加可忽略不计。
优点。由于时钟节拍将决定切换时间,因此任务不太可能从任务中的其他线程那里占用时间片。此外,I/O 阻塞不是问题。最后,如果编码正确,该进程可以自动利用 SMP,并且随着每个添加的 CPU,运行速度会逐步加快。
组合
一些实现同时支持用户空间和内核空间线程。这为运行中的任务提供了两者的优点。然而,由于 Linux 的内核空间线程几乎与用户空间线程性能相当,因此使用用户线程的唯一优势将是协作式多任务处理。
![]() |
![]() |
![]() |
![]() |
![]() |
[上一页] | [首页] | [词典] | [电子邮件作者] | [下一页] |