| Current File : //usr/share/man/zh_CN.UTF-8/man5/threads.5 |
'\" te
.\" Copyright (c) 2008, 2014, Oracle and/or its affiliates.All rights reserved.
.TH threads 5 "2014 年 4 月 23 日" "SunOS 5.11" "标准、环境和宏"
.SH 名称
threads, pthreads \- POSIX pthread 和 Solaris 线程概念
.SH 用法概要
.SS "POSIX"
.LP
.nf
cc –mt [ \fIflag\fR... ] \fIfile\fR... [ \fI library\fR... ]
.fi
.LP
.nf
#include <pthread.h>
.fi
.SS "Solaris"
.LP
.nf
cc –mt [ \fIflag\fR... ] \fIfile\fR... [ \fI library\fR... ]
.fi
.LP
.nf
#include <sched.h>
.fi
.LP
.nf
#include <thread.h>
.fi
.SH 描述
.sp
.LP
POSIX 和 Solaris 线程在 \fBlibc\fR(3LIB) 中均具有各自的实现。这两个实现可交互操作,其功能相似并可在同一应用程序中使用。只有 POSIX 线程保证可完全移植到符合 POSIX 的其他环境。POSIX 和 Solaris 线程需要不同的源,包括文件和链接系统信息库。请参见“用法概要”\fB\fR部分。
.SS "相似之处"
.sp
.LP
大部分 POSIX 和 Solaris 线程函数互相对应。POSIX 函数名称具有 “\fBpthread\fR” 前缀(信号名称除外)。相似的 POSIX 和 Solaris 函数的函数名称也具有相似的结尾。通常,相似的 POSIX 和 Solaris 函数的参数数目和用法相同。
.SS "不同之处"
.sp
.LP
POSIX pthread 和 Solaris 线程的不同之处在于:
.RS +4
.TP
.ie t \(bu
.el o
POSIX 线程的可移植性更好。
.RE
.RS +4
.TP
.ie t \(bu
.el o
POSIX 线程根据可配置的属性对象为每个线程建立特性。
.RE
.RS +4
.TP
.ie t \(bu
.el o
POSIX pthread 实现了线程取消。
.RE
.RS +4
.TP
.ie t \(bu
.el o
POSIX pthread 强制执行调度算法。
.RE
.RS +4
.TP
.ie t \(bu
.el o
POSIX pthread 允许使用 \fBfork\fR(2) 调用的清理处理程序。
.RE
.RS +4
.TP
.ie t \(bu
.el o
可暂停和继续执行 Solaris 线程。
.RE
.RS +4
.TP
.ie t \(bu
.el o
Solaris 线程实现守护进程线程,进程不会等待其终止。
.RE
.SH 函数比较
.sp
.LP
下表对 POSIX pthread 和 Solaris 线程函数进行了比较。当 POSIX pthread 或 Solaris 线程中没有可比较的接口时,列中会显示连字符 (\fB–\fR)。
.SS "与创建有关的函数"
.sp
.sp
.TS
tab();
lw(2.75i) lw(2.75i)
lw(2.75i) lw(2.75i)
.
\fBPOSIX\fR\fBSolaris\fR
\fBpthread_create()\fR\fBthr_create()\fR
\fBpthread_attr_init()\fR\fB–\fR
\fBpthread_attr_setdetachstate()\fR\fB–\fR
\fBpthread_attr_getdetachstate()\fR\fB–\fR
\fBpthread_attr_setinheritsched()\fR\fB–\fR
\fBpthread_attr_getinheritsched()\fR\fB–\fR
\fBpthread_attr_setschedparam()\fR\fB–\fR
\fBpthread_attr_getschedparam()\fR\fB–\fR
\fBpthread_attr_setschedpolicy()\fR\fB–\fR
\fBpthread_attr_getschedpolicy()\fR\fB–\fR
\fBpthread_attr_setscope()\fR\fB–\fR
\fBpthread_attr_getscope()\fR\fB–\fR
\fBpthread_attr_setstackaddr()\fR\fB–\fR
\fBpthread_attr_getstackaddr()\fR\fB–\fR
\fBpthread_attr_setstacksize()\fR\fB–\fR
\fBpthread_attr_getstacksize()\fR\fB–\fR
\fBpthread_attr_getguardsize()\fR\fB–\fR
\fBpthread_attr_setguardsize()\fR\fB–\fR
\fBpthread_attr_destroy()\fR\fB–\fR
\fB–\fR\fBthr_min_stack()\fR
.TE
.SS "与退出有关的函数"
.sp
.sp
.TS
tab();
lw(2.75i) lw(2.75i)
lw(2.75i) lw(2.75i)
.
\fBPOSIX\fR\fBSolaris\fR
\fBpthread_exit()\fR\fBthr_exit()\fR
\fBpthread_join()\fR\fBthr_join()\fR
\fBpthread_detach()\fR\fB–\fR
.TE
.SS "与线程特定数据有关的函数"
.sp
.sp
.TS
tab();
lw(2.75i) lw(2.75i)
lw(2.75i) lw(2.75i)
.
\fBPOSIX\fR\fBSolaris\fR
\fBpthread_key_create()\fR\fBthr_keycreate()\fR
\fBpthread_setspecific()\fR\fBthr_setspecific()\fR
\fBpthread_getspecific()\fR\fBthr_getspecific()\fR
\fBpthread_key_delete()\fR\fB–\fR
.TE
.SS "与信号有关的函数"
.sp
.sp
.TS
tab();
lw(2.75i) lw(2.75i)
lw(2.75i) lw(2.75i)
.
\fBPOSIX\fR\fBSolaris\fR
\fBpthread_sigmask()\fR\fBthr_sigsetmask()\fR
\fBpthread_kill()\fR\fBthr_kill()\fR
.TE
.SS "与 ID 有关的函数"
.sp
.sp
.TS
tab();
lw(2.75i) lw(2.75i)
lw(2.75i) lw(2.75i)
.
\fBPOSIX\fR\fBSolaris\fR
\fBpthread_self()\fR\fBthr_self()\fR
\fBpthread_equal()\fR\fB–\fR
\fB–\fR\fBthr_main()\fR
.TE
.SS "与调度有关的函数"
.sp
.sp
.TS
tab();
lw(2.75i) lw(2.75i)
lw(2.75i) lw(2.75i)
.
\fBPOSIX\fR\fBSolaris\fR
\fB–\fR\fBthr_yield()\fR
\fB–\fR\fBthr_suspend()\fR
\fB–\fR\fBthr_continue()\fR
\fBpthread_setconcurrency()\fR\fBthr_setconcurrency()\fR
\fBpthread_getconcurrency()\fR\fBthr_getconcurrency()\fR
\fBpthread_setschedparam()\fR\fBthr_setprio()\fR
\fBpthread_setschedprio()\fR\fBthr_setprio()\fR
\fBpthread_getschedparam()\fR\fBthr_getprio()\fR
.TE
.SS "与取消有关的函数"
.sp
.sp
.TS
tab();
lw(2.75i) lw(2.75i)
lw(2.75i) lw(2.75i)
.
\fBPOSIX\fR\fBSolaris\fR
\fBpthread_cancel()\fR\fB–\fR
\fBpthread_setcancelstate()\fR\fB–\fR
\fBpthread_setcanceltype()\fR\fB–\fR
\fBpthread_testcancel()\fR\fB–\fR
\fBpthread_cleanup_pop()\fR\fB–\fR
\fBpthread_cleanup_push()\fR\fB–\fR
.TE
.SS "与互斥锁有关的函数"
.sp
.sp
.TS
tab();
lw(3.85i) lw(1.65i)
lw(3.85i) lw(1.65i)
.
\fBPOSIX\fR\fBSolaris\fR
\fBpthread_mutex_init()\fR\fBmutex_init()\fR
\fBpthread_mutexattr_init()\fR\fB–\fR
\fBpthread_mutexattr_setpshared()\fR\fB–\fR
\fBpthread_mutexattr_getpshared()\fR\fB–\fR
\fBpthread_mutexattr_setprotocol()\fR\fB–\fR
\fBpthread_mutexattr_getprotocol()\fR\fB–\fR
\fBpthread_mutexattr_setprioceiling()\fR\fB–\fR
\fBpthread_mutexattr_getprioceiling()\fR\fB–\fR
\fBpthread_mutexattr_settype()\fR\fB–\fR
\fBpthread_mutexattr_gettype()\fR\fB–\fR
\fBpthread_mutexattr_setrobust()\fR\fB–\fR
\fBpthread_mutexattr_getrobust()\fR\fB–\fR
\fBpthread_mutexattr_destroy()\fR\fB–\fR
\fBpthread_mutex_setprioceiling()\fR\fB–\fR
\fBpthread_mutex_getprioceiling()\fR\fB–\fR
\fBpthread_mutex_lock()\fR\fBmutex_lock()\fR
\fBpthread_mutex_trylock()\fR\fBmutex_trylock()\fR
\fBpthread_mutex_unlock()\fR\fBmutex_unlock()\fR
\fBpthread_mutex_destroy()\fR\fBmutex_destroy()\fR
.TE
.SS "与条件变量有关的函数"
.sp
.sp
.TS
tab();
lw(2.75i) lw(2.75i)
lw(2.75i) lw(2.75i)
.
\fBPOSIX\fR\fBSolaris\fR
\fBpthread_cond_init()\fR\fBcond_init()\fR
\fBpthread_condattr_init()\fR\fB–\fR
\fBpthread_condattr_setpshared()\fR\fB–\fR
\fBpthread_condattr_getpshared()\fR\fB–\fR
\fBpthread_condattr_destroy()\fR\fB–\fR
\fBpthread_cond_wait()\fR\fBcond_wait()\fR
\fBpthread_cond_timedwait()\fR\fBcond_timedwait()\fR
\fBpthread_cond_signal()\fR\fBcond_signal()\fR
\fBpthread_cond_broadcast()\fR\fBcond_broadcast()\fR
\fBpthread_cond_destroy()\fR\fBcond_destroy()\fR
.TE
.SS "与读取器/写入器锁定有关的函数"
.sp
.sp
.TS
tab();
lw(2.75i) lw(2.75i)
lw(2.75i) lw(2.75i)
.
\fBPOSIX\fR\fBSolaris\fR
\fBpthread_rwlock_init()\fR\fBrwlock_init()\fR
\fBpthread_rwlock_rdlock()\fR\fBrw_rdlock()\fR
\fBpthread_rwlock_tryrdlock()\fR\fBrw_tryrdlock()\fR
\fBpthread_rwlock_wrlock()\fR\fBrw_wrlock()\fR
\fBpthread_rwlock_trywrlock()\fR\fBrw_trywrlock()\fR
\fBpthread_rwlock_unlock()\fR\fBrw_unlock()\fR
\fBpthread_rwlock_destroy()\fR\fBrwlock_destroy()\fR
\fBpthread_rwlockattr_init()\fR\fB–\fR
\fBpthread_rwlockattr_destroy()\fR\fB–\fR
\fBpthread_rwlockattr_getpshared()\fR\fB–\fR
\fBpthread_rwlockattr_setpshared()\fR\fB–\fR
.TE
.SS "与信号有关的函数"
.sp
.sp
.TS
tab();
lw(2.75i) lw(2.75i)
lw(2.75i) lw(2.75i)
.
\fBPOSIX\fR\fBSolaris\fR
\fBsem_init()\fR\fBsema_init()\fR
\fBsem_open()\fR\fB–\fR
\fBsem_close()\fR\fB–\fR
\fBsem_wait()\fR\fBsema_wait()\fR
\fBsem_trywait()\fR\fBsema_trywait()\fR
\fBsem_post()\fR\fBsema_post()\fR
\fBsem_getvalue()\fR\fB–\fR
\fBsem_unlink()\fR\fB–\fR
\fBsem_destroy()\fR\fBsema_destroy()\fR
.TE
.SS "与 fork( ) 清理有关的函数"
.sp
.sp
.TS
tab();
lw(2.75i) lw(2.75i)
lw(2.75i) lw(2.75i)
.
\fBPOSIX\fR\fBSolaris\fR
\fBpthread_atfork()\fR\fB–\fR
.TE
.SS "与限制有关的函数"
.sp
.sp
.TS
tab();
lw(2.75i) lw(2.75i)
lw(2.75i) lw(2.75i)
.
\fBPOSIX\fR\fBSolaris\fR
\fBpthread_once()\fR\fB–\fR
.TE
.SS "与调试有关的函数"
.sp
.sp
.TS
tab();
lw(2.75i) lw(2.75i)
lw(2.75i) lw(2.75i)
.
\fBPOSIX\fR\fBSolaris\fR
\fB–\fR\fBthr_stksegment()\fR
.TE
.SH 锁定
.SS "同步"
.sp
.LP
多线程行为是异步的,因此针对并发和并行处理进行了优化。由于线程(始终来自同一进程,有时来自多个进程)相互之间共享全局数据,因此无法保证它们对任何时间点的共享数据具有独占访问权限。要获得对共享数据的独占访问权限,需要在线程之间进行同步。POSIX 和 Solaris 均实现了四种同步机制:互斥锁、条件变量、读取器/写入器锁定(\fI优化的频繁读、少量写互斥锁\fR)以及信号。
.sp
.LP
同步多个线程会大大降低线程并发性。同步的粒度越粗,即锁定的代码块越大,并发性就越小。
.SS "MT \fBfork()\fR"
.sp
.LP
如果线程程序调用 \fBfork\fR(2),它会隐式调用只复制调用线程的 \fBfork1\fR(2)。如果整个进程中还有任何待处理的互斥锁,则应用程序应在调用 \fBfork()\fR 之前调用 \fBpthread_atfork\fR(3C) 等待并获取这些互斥锁。
.SH 调度
.SS "POSIX 线程"
.sp
.LP
Solaris 支持以下三种 POSIX 调度策略:
.sp
.ne 2
.mk
.na
\fB\fBSCHED_OTHER\fR\fR
.ad
.RS 15n
.rt
传统分时调度策略。该策略基于分时 (timesharing, TS) 调度类。
.RE
.sp
.ne 2
.mk
.na
\fB\fBSCHED_FIFO\fR\fR
.ad
.RS 15n
.rt
先入先出调度策略。如果不被更高优先级抢占,根据此策略调度的线程将会继续执行直至完成。此类线程属于实时 (real-time, RT) 调度类。调用进程必须在其有效集中声明 {\fBPRIV_PROC_PRIOCNTL\fR} 特权。
.RE
.sp
.ne 2
.mk
.na
\fB\fBSCHED_RR\fR\fR
.ad
.RS 15n
.rt
循环调度策略。如果不被更高优先级抢占,根据此策略调度的线程将在系统确定的时段内执行。此类线程属于实时 (real-time, RT) 调度类,调用进程必须在其有效集中声明 {\fBPRIV_PROC_PRIOCNTL\fR} 特权。
.RE
.sp
.LP
除了上述 POSIX 指定的调度策略以外,Solaris 还支持以下调度策略:
.sp
.ne 2
.mk
.na
\fB\fBSCHED_IA\fR\fR
.ad
.RS 13n
.rt
根据 \fBpriocntl\fR(2) 中所述的交互式类 (Inter-Active Class, IA) 策略调度线程。
.RE
.sp
.ne 2
.mk
.na
\fB\fBSCHED_FSS\fR\fR
.ad
.RS 13n
.rt
根据 \fBpriocntl\fR(2) 中所述的公平份额类 (Fair-Share Class, FSS) 策略调度线程。
.RE
.sp
.ne 2
.mk
.na
\fB\fBSCHED_FX\fR\fR
.ad
.RS 13n
.rt
根据 \fBpriocntl\fR(2) 中所述的固定优先级类 (Fixed-Priority Class, FSS) 策略调度线程。
.RE
.SS "Solaris 线程"
.sp
.LP
唯一受支持的调度策略是 \fBSCHED_OTHER\fR,即基于 \fBTS\fR 调度类的分时。
.SH 错误
.sp
.LP
在多线程应用程序中,当有其他线程调用 \fBforkall\fR(2) 时,将会从阻止的系统调用返回 \fBEINTR\fR。
.SH 用法
.SS "\fB-mt\fR 编译器选项"
.sp
.LP
\fB-mt\fR 编译器选项会编译和链接多线程代码。它使用 -\fBD_REENTRANT\fR 编译源文件并适当扩大支持系统信息库集。
.SH 属性
.sp
.LP
有关下列属性的说明,请参见 \fBattributes\fR(5):
.sp
.sp
.TS
tab() box;
cw(2.75i) |cw(2.75i)
lw(2.75i) |lw(2.75i)
.
属性类型属性值
_
MT 级别MT-Safe、Fork 1-Safe
.TE
.SH 另请参见
.sp
.LP
\fBcrle\fR(1)、\fBfork\fR(2)、\fBpriocntl\fR(2)、\fBlibpthread\fR(3LIB)、\fBlibrt\fR(3LIB)、\fBlibthread\fR(3LIB)、\fBpthread_atfork\fR(3C)、\fBpthread_create\fR(3C)、\fBattributes\fR(5)、\fBprivileges\fR(5)、\fBstandards\fR(5)
.sp
.LP
\fI《Oracle Solaris 11.3 Linkers and Libraries Guide》\fR