争用作用域和并发级别

用户线程的 争用作用域 定义如何将其映射到内核线程。

线程库定义了以下争用 作用域:
PTHREAD_SCOPE_PROCESS
进程争用作用域,有时候也称为局部争用作用域。 指定根据进程中所有其他局部争用作用域线程进行 调度的线程。 进程争用作用域用户线程是一个与进程中其他进程争用作用域用户线程共享内核线程的用户线程。 M:1 线程模型中的所有 用户线程都有进程争用作用域。

AIX 7.3 开始,不再支持这种争用范围。

PTHREAD_SCOPE_SYSTEM
系统争用作用域,有时称为全局争用作用域。 指定根据系统中所有其他线程进行调度并直接映射到一个 内核线程的线程。 1:1 线程模型中的所有用户线程都有系统争用作用域。

AIX 7.3开始,仅支持此争用作用域。

在 M:N 线程模型中,用户线程可以有系统争用作用域或进程争用作用域。 所以,M:N 线程模型通常称 为混合域模型。

并发级别是 M:N 线程库的属性。 它定义了用于运行进程争用作用域用户线程 的虚拟处理器的数目。 此数目不能超过进程争用作用域用户线程的数目并且通常由线程库动态设置。 系统还对可用的内核线程的数目设置 限制。

设置争用作用域

只有在线程创建之前,通过设置线程属性对象的争用作用域属性才能设置争用作用域。 pthread_attr_setscope 子例程设置属性的值;pthread_attr_getscope 将该值返回。

只有在混合作用域 M:N 库实现中此争用作用域才有意义。 TestImplementation 例程可以写成如下形式:
int TestImplementation()
{
        pthread_attr_t a;
        int result;

        pthread_attr_init(&a);
        switch (pthread_attr_setscope(&a, PTHREAD_SCOPE_PROCESS))
        {
                case 0:          result = LIB_MN; break;
                case ENOTSUP:    result = LIB_11; break;
                case ENOSYS:     result = NO_PRIO_OPTION; break;
                default:         result = ERROR; break;
        }

        pthread_attr_destroy(&a);
        return result;
}

争用作用域对调度的影响

线程的争用作用域影响了它的调度。 每个争用作用域线程都绑定到一个内核线程。 所以,更改全局用户线程的调度 策略和优先级将导致底层的内核线程的调度策略和优先级的更改。

AIX中,只有具有 root 用户权限的内核线程才能使用固定优先级调度策略 (FIFO 或 round-robin)。 如果调用 线程有系统争用作用域但是没有超级权限,那么以下代码始终返回 EPERM 错误码。 如果调用线程有进程争用 作用域,该代码将不会失败。
schedparam.sched_priority = 3;
pthread_setschedparam(pthread_self(), SCHED_FIFO, schedparam);
注: 不需要 root 用户权限来控制具有进程争用作用域的用户线程的调度参数。

局部用户线程可以在值的有效范围内设置任意调度策略和优先级。 然而,两个具有相同调度策略和优先级但是有 不同争用作用域的线程将不会按照相同的方式进行调度。 具有进程争用作用域的线程由内核线程执行,其调度参数由库设置。