threads
, pthreads
- POSIX pthread と Solaris スレッドの概念
形式
POSIX
cc –mt [ flag... ] file... [ -lrt library... ]
#include <pthread.h>
Solaris
cc –mt [ flag... ] file... [ library... ]
#include <sched.h>
#include <thread.h>
機能説明
POSIX スレッドと Solaris スレッドにはそれぞれ、libc(3LIB) 内に独自の実装があります。両方の実装は相互運用可能であり、それぞれの機能は類似しているため、同じアプリケーション内で使用できます。POSIX に準拠したほかの環境に完全に移植できることが保証されているのは POSIX スレッドだけです。POSIX スレッドと Solaris スレッドには、異なるソース、インクルードファイル、およびリンクライブラリが必要です。「形式」を参照してください。
類似点
POSIX と Solaris のスレッド化関数のほとんどには、互いに対応する関数があります。セマフォー名を除き、POSIX 関数名には「pthread」の接頭辞が付いています。類似した POSIX 関数と Solaris 関数は、関数名の末尾が類似しています。通常、類似した POSIX 関数と Solaris
関数には、同じ数と用途の引数があります。
相違点
POSIX pthread と Solaris スレッドは、次の点で異なっています:
POSIX スレッドの方が移植性があります。
POSIX スレッドでは、構成可能な属性オブジェクトに従って、各スレッドの特性が確立されています。
POSIX pthread には、スレッド取り消しが実装されています。
POSIX pthread では、スケジューリングのアルゴリズムが適用されます。
POSIX pthread では、fork(2) 呼び出しのためのクリーンアップハンドラが許可されます。
Solaris スレッドは中断したり、続行したりできます。
Solaris スレッドには、プロセスがその消滅を待たないデーモンスレッドが実装されています。
関数の比較
次の表に、POSIX pthread と Solaris スレッドの関数の比較を示します。POSIX pthread または Solaris スレッドのどちらかで比較可能なインタフェースがない場合は、その列にハイフン (–) が表示されます。
作成に関連した関数
POSIX |
Solaris |
pthread_create() |
thr_create() |
pthread_attr_init() |
– |
pthread_attr_setdetachstate() |
– |
pthread_attr_getdetachstate() |
– |
pthread_attr_setinheritsched() |
– |
pthread_attr_getinheritsched() |
– |
pthread_attr_setschedparam() |
– |
pthread_attr_getschedparam() |
– |
pthread_attr_setschedpolicy() |
– |
pthread_attr_getschedpolicy() |
– |
pthread_attr_setscope() |
– |
pthread_attr_getscope() |
– |
pthread_attr_setstackaddr() |
– |
pthread_attr_getstackaddr() |
– |
pthread_attr_setstacksize() |
– |
pthread_attr_getstacksize() |
– |
pthread_attr_getguardsize() |
– |
pthread_attr_setguardsize() |
– |
pthread_attr_destroy() |
– |
– |
thr_min_stack() |
|
終了に関連した関数
POSIX |
Solaris |
pthread_exit() |
thr_exit() |
pthread_join() |
thr_join() |
pthread_detach() |
– |
|
スレッド固有のデータに関連した関数
POSIX |
Solaris |
pthread_key_create() |
thr_keycreate() |
pthread_setspecific() |
thr_setspecific() |
pthread_getspecific() |
thr_getspecific() |
pthread_key_delete() |
– |
|
シグナルに関連した関数
POSIX |
Solaris |
pthread_sigmask() |
thr_sigsetmask() |
pthread_kill() |
thr_kill() |
|
ID に関連した関数
POSIX |
Solaris |
pthread_self() |
thr_self() |
pthread_equal() |
– |
– |
thr_main() |
|
スケジューリングに関連した関数
POSIX |
Solaris |
– |
thr_yield() |
– |
thr_suspend() |
– |
thr_continue() |
pthread_setconcurrency() |
thr_setconcurrency() |
pthread_getconcurrency() |
thr_getconcurrency() |
pthread_setschedparam() |
thr_setprio() |
pthread_setschedprio() |
thr_setprio() |
pthread_getschedparam() |
thr_getprio() |
|
取り消しに関連した関数
POSIX |
Solaris |
pthread_cancel() |
– |
pthread_setcancelstate() |
– |
pthread_setcanceltype() |
– |
pthread_testcancel() |
– |
pthread_cleanup_pop() |
– |
pthread_cleanup_push() |
– |
|
相互排他ロックに関連した関数
POSIX |
Solaris |
pthread_mutex_init() |
mutex_init() |
pthread_mutexattr_init() |
– |
pthread_mutexattr_setpshared() |
– |
pthread_mutexattr_getpshared() |
– |
pthread_mutexattr_setprotocol() |
– |
pthread_mutexattr_getprotocol() |
– |
pthread_mutexattr_setprioceiling() |
– |
pthread_mutexattr_getprioceiling() |
– |
pthread_mutexattr_settype() |
– |
pthread_mutexattr_gettype() |
– |
pthread_mutexattr_setrobust() |
– |
pthread_mutexattr_getrobust() |
– |
pthread_mutexattr_destroy() |
– |
pthread_mutex_setprioceiling() |
– |
pthread_mutex_getprioceiling() |
– |
pthread_mutex_lock() |
mutex_lock() |
pthread_mutex_trylock() |
mutex_trylock() |
pthread_mutex_unlock() |
mutex_unlock() |
pthread_mutex_destroy() |
mutex_destroy() |
|
条件変数に関連した関数
POSIX |
Solaris |
pthread_cond_init() |
cond_init() |
pthread_condattr_init() |
– |
pthread_condattr_setpshared() |
– |
pthread_condattr_getpshared() |
– |
pthread_condattr_destroy() |
– |
pthread_cond_wait() |
cond_wait() |
pthread_cond_timedwait() |
cond_timedwait() |
pthread_cond_signal() |
cond_signal() |
pthread_cond_broadcast() |
cond_broadcast() |
pthread_cond_destroy() |
cond_destroy() |
|
読み取り書き込みロックに関連した関数
POSIX |
Solaris |
pthread_rwlock_init() |
rwlock_init() |
pthread_rwlock_rdlock() |
rw_rdlock() |
pthread_rwlock_tryrdlock() |
rw_tryrdlock() |
pthread_rwlock_wrlock() |
rw_wrlock() |
pthread_rwlock_trywrlock() |
rw_trywrlock() |
pthread_rwlock_unlock() |
rw_unlock() |
pthread_rwlock_destroy() |
rwlock_destroy() |
pthread_rwlockattr_init() |
– |
pthread_rwlockattr_destroy() |
– |
pthread_rwlockattr_getpshared() |
– |
pthread_rwlockattr_setpshared() |
– |
|
セマフォーに関連した関数
POSIX |
Solaris |
sem_init() |
sema_init() |
sem_open() |
– |
sem_close() |
– |
sem_wait() |
sema_wait() |
sem_trywait() |
sema_trywait() |
sem_post() |
sema_post() |
sem_getvalue() |
– |
sem_unlink() |
– |
sem_destroy() |
sema_destroy() |
|
fork( ) クリーンアップに関連した関数
POSIX |
Solaris |
pthread_atfork() |
– |
|
制限に関連した関数
POSIX |
Solaris |
pthread_once() |
– |
|
デバッグに関連した関数
POSIX |
Solaris |
– |
thr_stksegment() |
|
ロック
同期
マルチスレッド動作は非同期であるため、並列処理や並行処理のために最適化されます。各スレッドは (常に同じプロセス内から、場合によっては複数のプロセスから) 互いにグローバルデータを共有しますが、共有データへの排他的アクセスが任意の特定の時点で保証されているとは限りません。共有データへの相互に排他的なアクセスをセキュリティーで保護するには、スレッド間の同期が必要です。POSIX と Solaris のどちらにも、次の 4 つの同期メカニズムが実装されています: 相互排他ロック、条件変数、読み取り書き込みロック (頻繁な読み取りと不定期の書き込みのための最適化された相互排他ロック)、セマフォー。
複数のスレッドを同期させると、それらの並行性が低下します。同期の粒度が粗い程 (つまり、ロックされるコードのブロックが大きい程)、並行性は低くなります。
MT の fork()
スレッドのプログラムが fork(2) を呼び出した場合、呼び出し元スレッドのみを複製する fork1(2) が暗黙的に呼び出されます。プロセス全体にわたって未処理の相互排他ロックが存在する場合、アプリケーションは fork() を呼び出す前に、待機してこれらの相互排他ロックを取得するために pthread_atfork(3C) を呼び出すようにしてください。
スケジューリング
POSIX スレッド
Solaris は、次の 3 つの POSIX スケジューリングポリシーをサポートしています:
- SCHED_OTHER
従来のタイムシェアリングスケジューリングポリシー。これは、タイムシェアリング (TS) スケジューリングクラスに基づいています。
- SCHED_FIFO
先入れ先出しスケジューリングポリシー。このポリシーに従ってスケジュールされたスレッドは、より高い優先順位によって横取りされなければ、完了まで続行されます。このようなスレッドは、リアルタイム (RT) スケジューリングクラスに属します。呼び出し元プロセスの実効セットで {PRIV_PROC_PRIOCNTL} 特権が表明されている必要があります。
- SCHED_RR
ラウンドロビンスケジューリングポリシー。このポリシーに従ってスケジュールされたスレッドは、より高い優先順位によって横取りされなければ、システムで決定された期間にわたって実行されます。このようなスレッドは、リアルタイム (RT) スケジューリングクラスに属し、呼び出し元プロセスの実効セットで {PRIV_PROC_PRIOCNTL} 特権が表明されている必要があります。
上の POSIX で指定されたスケジューリングポリシーに加えて、Solaris では次のスケジューリングポリシーもサポートされています:
- SCHED_IA
スレッドは、priocntl(2) で説明されている対話型クラス (IA) ポリシーに従ってスケジュールされます。
- SCHED_FSS
スレッドは、priocntl(2) で説明されている公平配分クラス (FSS) ポリシーに従ってスケジュールされます。
- SCHED_FX
スレッドは、priocntl(2) で説明されている固定優先順位クラス (FX) ポリシーに従ってスケジュールされます。
Solaris スレッド
サポートされている唯一のスケジューリングポリシーが、TS スケジューリングクラスに基づいた SCHED_OTHER (タイムシェアリング) です。
エラー
マルチスレッドアプリケーションでは、別のスレッドが forkall(2) を呼び出したとき、ブロックしているシステムコールから EINTR が返されることがあります。
使用法
-mt コンパイラオプション
-mt コンパイラオプションは、マルチスレッド対応コードのためのコンパイルとリンクを行います。このオプションは -D_REENTRANT でソースファイルをコンパイルし、一連のサポートライブラリを正しく拡張します。
属性
属性についての詳細は、マニュアルページの attributes(5) を参照してください。
関連項目
crle(1)、fork(2)、priocntl(2)、libpthread(3LIB)、librt(3LIB)、libthread(3LIB)、pthread_atfork(3C)、pthread_create(3C)、attributes(5)、privileges(5)、standards(5)
『リンカーとライブラリ』