线程库选项

此部分描述了线程、互斥对象和条件变量的特殊属性。

线程库的 POSIX 标准指定某些部件的实现是可选的。 由线程 库 API 定义的所有子例程始终可用。 根据这些可用的选项,某些子例程可能无法实现。 未实现的子例程也可以被应用程序调用,但它们始终返回 ENOSYS 错误码。

堆栈属性

为每个线程分配一个堆栈。 堆栈管理与实现相关。 因此,以下信息仅适用于AIX,尽管其他系统可能也有类似功能。

在创建线程时动态分配堆栈。 通过使用高级线程属性,用户就可以控制堆栈大小和堆栈地址。 以下信息不适用于 由系统创建的初始线程。

堆栈大小

堆栈大小选项启用对线程属性对象的 stacksize 属性的控制。 该属性指定用于已创建的 线程最小堆栈大小。

stacksize 属性在 AIX中定义。 该选项实现后,那么可以使用以下属性和子例程:

stacksize 属性的缺省值是 96 KB。 stacksize 属性的最小值是 16 KB。 如果指定的值小于最小值,那么分配最小值。

在线程库的 AIX 实现中,将为每个创建的线程分配一个称为 用户线程区域的数据块。 该区域被分成以下部分:
  • 红色区域,该区域既是读保护又是写保护的,用于进行堆栈溢出检测。 在使用大页面的程序中没有红色 区域。
  • 缺省堆栈。
  • pthread 结构。
  • 线程结构。
  • 线程属性结构。
注: 此处描述的用户线程区域与 AIX 内核中使用的 uthread 结构没有关系。 只有在用户 方式下才能访问用户线程区域并且该区域专门由例程库处理,而且 uthread 结构仅存在于内核环境中。

堆栈地址 POSIX 选项

堆栈地址选项启用对线程属性对象的 stackaddr 属性的控制。 该结构指定用于已创建 线程的堆栈的存储器位置。

该选项实现后,那么可以使用以下属性和子例程:

如果未指定任何堆栈地址,那么系统为该堆栈分配任意地址。 如果必须让堆栈位于已知位置,您可以 使用 stackaddr 属性。 例如,如果需要非常大的堆栈,那么可将它的地址设为从未使用过的段,以保证分配 能成功。

如果在调用 pthread_create 子例程时指定了堆栈地址,那么系统将尝试在给定地址分配堆栈。 如果分配失败,pthread_create 子例程返回 EINVAL。 由于 pthread_attr_setstackaddr 子例程没有实际分配堆栈,所以如果指定的堆栈地址超出寻址空间,那么该子例程仅仅返回一个错误。

优先级调度 POSIX 选项

优先级调度选项在线程级启用对执行调度的控制。 如果禁用该选项,那么进程内的所有线程将共享进程的调度属性。 如果启用该选项,那么 每个线程都有自己的调度属性。 对于局部争用作用域线程,在进程级通过库调度程序处理调度属性,而对于全局争用作用域线程,那么在系统级由内核调度程序处理调度属性。

该选项实现后,那么可以使用以下属性和子例程:

检查选项的可用性

可以在编译时或运行时检查选项。 应该在使用可移植程序之前检查选项的可用性,这样将它们移植到其他系统时就不需要重写该程序。

编译时检查

当一个选项不可用时,您可以停止编译,如以下示例所示:
#ifndef _POSIX_THREAD_ATTR_STACKSIZE
#error "The stack size POSIX option is required"
#endif
pthread.h 头文件也定义了其他头文件或程序可以使用的以下符号:
_POSIX_REENTRANT_FUNCTIONS
表示需要重入 (reentrant) 函数
_POSIX_THREADS
表示线程库的实现

运行时检查

sysconf 子例程可用于获取执行程序的系统上选项的可用性。 当在具有二进制兼容性的系统 (例如两个版本的 AIX) 之间移植程序时,这很有用。

以下列表指示与每个选项相关联的符号以及必须用于 sysconf 子例程的 Name 参数的符号。 符号常量定义在 unistd.h 头文件中。

堆栈地址
_sc_thread_attr_stackaddr
堆栈大小
_sc_thread_attr_stacksize
优先级调度
_sc_thread_priority_scheduling
优先级继承
_sc_thread_prio_inherit
优先级保护
_sc_thread_prio_protect
进程共享
_sc_thread_process_shared
要检查常规选项,请使用带有以下 Name 参数值的 sysconf 子例程:
_SC_REENTRANT_FUNCTIONS
表示需要 Reentrant 函数。
_SC_THREADS
表示线程库的实现。

进程共享

AIX和大多数UNIX系统允许多个进程共享一个共同的数据空间(称为共享内存)。条件变量和互斥体的进程共享属性旨在允许在共享内存中分配这些对象,以支持属于不同进程的线程之间的同步。 但是,由于没有用于共享内存管理的业界标准接口,因此未在 AIX 线程库中实现进程共享 POSIX 选项。

线程数据类型

为线程库定义了以下数据类型。 这些数据类型的定义随 着系统的不同而不同:
PTHREAD_T
标识一个线程
pthread_attr_t
标识线程属性对象
pthread_cond_t
标识条件变量
pthread_condattr_t
标识条件属性对象
pthread_key_t
标识特定于线程的数据键
pthread_mutex_t
标识互斥对象
pthread_mutexattr_t
标识互斥属性对象
pthread_once_t
标识一次初始化的对象

限制和缺省值

线程库有某些与实现相关的限制和缺省值。 可以通过符号常量检索这些限制和缺省值以提高程序的可移植性:
  • 每个进程中线程的最大数目是 512。 可以使用 pthread.h 头文件中定义 的 PTHREAD_THREADS_MAX 符号常量在编译时检索线程的最大数目。 如果应用程序 使用 -D_LARGE_THREADS 标记编译,那么每个进程的线程的最大数目是 32767。
  • 线程的最小堆栈大小为 8 K。 缺省堆栈大小为 96 KB。 可以使用 pthread.h 头文件中定义 的 PTHREAD_STACK_MIN 符号常量在编译时检索该数目。
    注: 最大堆栈大小为 256 MB ,即段大小。 此限制由 pthread.h 头文件中的 PTHREAD_STACK_MAX 指示。
  • 特定于线程的数据键的最大数目限制为 508。 可以使用 pthread.h 头文件中定义 的 PTHREAD_KEYS_MAX 符号常量在编译时检索该数目。

缺省属性值

线程属性对象的缺省值由以下符号常量在 pthread.h 头文件中定义:
  • DEFAULT_DETACHSTATE 符号常量的缺省值是 PTHREAD_CREATE_DETACHED,该值 指定 detachstate 属性的缺省值。
  • DEFAULT_JOINABLE 符号常量的缺省值是 PTHREAD_CREATE_JOINABLE,该值指定可连接状态的缺省值。
  • DEFAULT_INHERIT 符号常量的缺省值是 PTHREAD_INHERIT_SCHED,该值指 定 inheritsched 属性的缺省值。
  • DEFAULT_PRIO 符号常量的缺省值为 1 ,用于指定sched_prioschedparam 属性的字段。
  • DEFAULT_SCHED 符号常量的缺省值是 SCHED_OTHER,该值指定线程属性对象 的 schedpolicy 属性的缺省值。
  • DEFAULT_SCOPE 符号常量的缺省值是 PTHREAD_SCOPE_LOCAL,该值 指定 contention-scope 属性的缺省值。