多线程编程指南

LWP 和调度类

Solaris 内核具有三种调度类。优先级最高的调度类是实时 (RT) 类。优先级居中的调度类是 system。不能将 system 类应用于用户进程。优先级最低的调度类为分时 (TS) 类,也是缺省类。

系统将针对每个 LWP 维护调度类。创建进程时,初始 LWP 将继承调度类和在父进程中创建 LWP 的优先级。随着所创建进程数目的增多,其关联的 LWP 也会继承此调度类和优先级。

线程具有其基础 LWP 的调度类和优先级。进程中的每个 LWP 都有内核可见的唯一调度类和优先级。

线程优先级可以控制同步对象的争用情况。缺省情况下,LWP 处于分时类中。对于与计算绑定的多线程,线程优先级不是非常有用。对于使用 MT 库频繁执行同步的多线程应用程序,线程优先级更有意义。

调度类是由 priocntl(2) 设置的。指定前两个参数的方式确定只有调用 LWP 还是一个或多个进程的所有 LWP 受影响。priocntl() 的第三个参数是命令,可以是以下命令之一。

请注意,priocntl() 会影响与调用线程关联的 LWP 的调度。对于未绑定线程,返回对 priocntl() 的调用后,无法保证调用线程与受影响的 LWP 关联。

分时调度

分时调度可以在分时调度类的 LWP 中公平地分布处理资源。内核的其他部分可以在短时间内独占处理器,而不会缩短用户察觉的响应时间。

priocntl(2) 调用可以设置一个或多个进程的 nice(2) 级别。priocntl() 调用还会影响进程中所有分时类 LWP 的 nice() 级别。nice() 级别的范围通常为 0 到 +20,对于具有超级用户权限的进程,该范围为 -20 到 +20。值越低,优先级越高。

分时 LWP 的分发优先级是根据 LWP 的即时 CPU 使用率及其 nice() 级别计算出来的。nice() 级别指示 LWP 相对于分时调度程序的优先级。

nice() 值越大的 LWP 获得的总处理份额越小,但都为非零值。接收处理量较大的 LWP 的优先级与接收处理量很少或没有接收任何处理的 LWP 的优先级要低。

实时调度

可以将实时类 (RT) 应用于整个进程或应用于进程中的一个或多个 LWP。 必须具有超级用户权限才能使用实时类。

与分时类的 nice(2) 级别不同,可以分别或联合为分类为实时类的 LWP 指定优先级。priocntl(2) 调用将影响进程中所有实时 LWP 的属性。

调度程序始终会分发优先级最高的实时 LWP。当优先级较高的 LWP 可以运行时,优先级高的实时 LWP 优先于优先级较低的 LWP。优先的 LWP 置于其级别队列的开头。

实时 LWP 始终控制着处理器,直到优先处理了 LWP、LWP 暂停或更改了其实时优先级为止。RT 类的 LWP 绝对优先于 TS 类中的进程。

新的 LWP 将继承父进程或 LWP 的调度类。RT 类 LWP 将继承父进程的时间¤ù,无论是有限的还是无限的。

有限的时间片 LWP 将始终运行,直到 LWP 终止、中断了 I/O 事件、优先级较高的可运行实时进程优先于该 LWP 执行或时间片到期为止。

只有在 LWP 终止、中断或其他实时进程优先于该 LWP 执行,时间片无限的 LWP 才停止执行操作。

公平共享调度程序

公平共享调度程序 (fair share scheduler, FSS) 调度类允许根据份额来分配 CPU 时间。

缺省情况下,FSS 调度类与 TS 和交互式 (interactive, IA) 调度类使用相同的优先级范围(0 到 59)。进程中的所有 LWP 必须在同一调度类中运行。FSS 类将调度单个 LWP,而不是整个进程。因此,混合使用 FSS 和 TS/IA 类中的进程可能会导致在这两种情况下出现意外的调度行为。

TS/IA 或 FSS 调度类进程不会争用相同的 CPU。处理器集可以在系统中混合 TS/IA 与 FSS。但是,每个处理器集中的所有进程都必须属于 TS/IA 调度类或 FSS 调度类。

固定优先级调度

FX(固定优先级)调度类可以指定没有为适应资源占用而调整的固定优先级和时间量程。进程优先级只能由指定优先级的进程或具有适当权限的进程进行更改。有关 FX 的更多信息,请参见 priocntl(1) 和 dispadmin(1M) 手册页。

此类中的线程与 TS 和交互式 (interactive, IA) 调度类共享相同的优先级范围(0 到 59)。TS 通常为缺省调度类。FX 通常与 TS 结合使用。