C11標準ライブラリ、C++11標準ライブラリ、POSIXスレッドのスレッドライブラリ(Pthreads) API比較。
各スレッドライブラリAPIを、“スレッド”、“CallOnce”、“排他制御(mutex)”、“条件変数(condition variable)”、“TLS(Thread Local Storage)”、その他機能に分類して比較する。表記簡略化のためC++11標準ライブラリは名前空間stdを省略している。
概略:
- C11はISO/IEC JTC1/SC22/WG14 N1570、C++11はISO/IEC JTC1/SC22/WG21 N3337、POSIXはIEEE Std 1003.1-2008に基づく。
- C11標準ライブラリとPOSIXスレッドライブラリのAPI体系はほぼ同一。*1
- C++11標準ライブラリはC11標準ライブラリ提供のスレッドサポート機能を包含し、C++言語機能テンプレートの利用によって利便性向上と型安全性を提供する。
ヘッダファイル
各スレッドライブラリにおいて機能別にincludeする必要のあるヘッダファイル。
C11 | C++11 | POSIX | |
---|---|---|---|
スレッド | threads.h | thread | pthreads.h time.h sched.h |
CallOnce | threads.h | mutex | pthreads.h |
排他制御 | threads.h | mutex | pthreads.h |
条件変数 | threads.h | condition_variable | pthreads.h |
TLS | (言語組込) threads.h |
(言語組込) | pthreads.h |
その他 | - | future | - |
C11におけるTLSは言語組み込み機能+標準ライブラリサポートで構成される。
C++11におけるTLSは言語組み込み機能のため、特定のヘッダincludeを必要としない。
スレッド
スレッドオブジェクトを表現する型と呼出可能な関数シグネチャ、スレッド作成/待機/比較といった操作を行う関数群。
C11 | C++11 | POSIX |
---|---|---|
thrd_t型 | threadクラス | pthread_t型 |
int (*)(void*) | 任意の関数オブジェクト | void* (*)(void*) |
thrd_create | threadコンストラクタ | pthread_create |
thrd_join | thread::join | pthread_join |
thrd_detach | thread::detach | pthread_detach |
thrd_exit | 関数オブジェクトからのreturn | pthread_exit |
thrd_current | this_thread::get_id | pthread_self |
thrd_equal | thread::get_id thread::id::operator== |
pthread_equal |
thrd_sleep | this_thread::sleep_for this_thread::sleep_until |
nanosleep[time.h] |
thrd_yield | this_thread::yield | sched_yield[sched.h] |
C11およびPOSIXではスレッド作成(create)関数に指定したユーザ定義関数の戻り値を、該当スレッドに対する待機(join)関数の戻り値として取得できる。
C++11では別スレッドにて実行された関数オブジェクトの戻り値は破棄される。スレッド間での値受け渡しを実装するには、別途future/promiseクラス[標準ヘッダfuture]を利用する必要がある。(→id:yohhoy:20120131)
スレッドキャンセル処理はPOSIXでのみ提供される。C11およびC++11において相当機能が必要な場合、条件変数等を用いて別途実装する必要がある。
CallOnce
CallOnce処理を実現するためのフラグ型と初期化定数、呼出可能な関数シグネチャとCallOnce関数。
C11 | C++11 | POSIX |
---|---|---|
once_flag型 | once_flag型 | pthread_once_t型 |
ONCE_FLAG_INITマクロ | - | PTHREAD_ONCE_INITマクロ |
void (*)(void) | 任意の関数オブジェクト | void (*)(void) |
call_once | call_once | pthread_once |
C++11におけるフラグ型once_flagはconstexprなデフォルトコンストラクタを持つため、特に初期化定数を必要としない。
排他制御
ミューテックスオブジェクトを表現する型と、ミューテックスのロック獲得/開放といった操作を行う関数群。C++11列のMutexは具体的なクラス名ではなく、mutex, recursive_mutex, timed_mutex, recursive_timed_mutex のいずれかを表す*2。
C11 | C++11 | POSIX |
---|---|---|
mtx_t型 | Mutexクラス | pthread_mutex_t型 |
mtx_init | Mutexコンストラクタ | pthread_mutex_init |
mtx_destroy | Mutexデストラクタ | pthread_mutex_destroy |
mtx_lock | Mutex::lock | pthread_mutex_lock |
mtx_unlock | Mutex::unlock | pthread_mutex_unlock |
mtx_trylock | Mutex::try_lock | pthread_mutex_trylock |
mtx_timedlock | Mutex::try_lock_for Mutex::try_lock_until |
pthread_mutex_timedlock |
Reader-Writerロック(pthread_rwlock_*
)やスピンロック(pthread_spin_*
)はPOSIXでのみ提供される。C11およびC++11において相当機能が必要な場合、条件変数やatomic変数等を用いて別途実装する必要がある。
ミューテックスの属性
ミューテックスオブジェクトの能力/属性; 再帰, タイムアウト付き待機 の表現方法。
- C11:初期化関数mtx_initの引数にて列挙型値mtx_plain, mtx_timed, mtx_recursiveまたはそのビット和を指定する*3。
- C++11:クラス型によって表現する。mutex, recursive_mutex, timed_mutex, recursive_timed_mutexクラスが提供される。
- POSIX:初期化関数thread_mutex_initの引数にてpthread_mutexattr_tオブジェクトを指定する。再帰ミューテックスの場合、同pthread_mutexattr_tオブジェクトへpthread_mutexattr_settype関数にてPTHREAD_MUTEX_RECURSIVE定数を指定する。
条件変数
条件変数オブジェクトを表現する型と、条件変数への通知/待機といった操作を行う関数群。
C11 | C++11 | POSIX |
---|---|---|
cnd_t型 | condition_variableクラス | pthread_cond_t型 |
cnd_init | condition_variableコンストラクタ | pthread_cond_init |
cnd_destroy | condition_variableデストラクタ | pthread_cond_destroy |
cnd_signal | condition_variable::notify_one | pthread_cond_signal |
cnd_broadcast | condition_variable::notify_all | pthread_cond_broadcast |
cnd_wait | condition_variable::wait | pthread_cond_wait |
cnd_timedwait | condition_variable::wait_until condition_variable::wait_for |
pthread_cond_timedwait |
C++11における条件変数オブジェクトにはcondition_variable_anyも存在する(表中では省略)。
バリア同期(pthread_barrier_*
)はPOSIXでのみ提供される。C11およびC++11において相当機能が必要な場合、条件変数等を用いて別途実装する必要がある。*4
TLS
TLS値を表現するキー型と、TLS値の設定/取得といった操作を行う関数群。
C11 | C++11 | POSIX |
---|---|---|
_Thread_local記憶域指定子 tss_t型 |
thread_local記憶域指定子 | pthread_key_t型 |
任意の型 void * |
任意の型 | void * |
(言語組込) tss_create |
(言語組込) | pthread_key_create |
(言語組込) tss_delete |
(言語組込) | pthread_key_delete |
(変数write) tss_set |
(変数write) | pthread_setspecific |
(変数read) tss_get |
(変数read) | pthread_getspecific |
POSIXにおけるTLS(TSS; Thread Specific Storage)は、キーと値(void*
型)を紐付ける方式で実現される。
C++11におけるTLSは言語組み込み機能のため、変数に対してthread_local指定を行うことで任意の型を利用できる。またcreate/delete相当は処理系により行われ、get/setは通常変数と同様に単に変数アクセスでよい。
C11におけるTLS/TSSは、_Thread_local指定による言語組み込みのスカラ型サポートと、標準ライブラリ関数によるデストラクト処理を伴うvoid*
型のサポートで実現される。また標準ヘッダthreads.hでは、下記のthread_localマクロを定義する。
#define thread_local _Thread_local
その他
タイムアウト付き待機関数で利用する時刻/時間表現型と現在時刻取得関数。
C11 | C++11 | POSIX |
---|---|---|
struct timespec型 | chrono::time_point<Clock, Duration>クラス chrono::duration<Rep, Period>クラス |
struct timespec型 |
timespec_get[time.h] | chrono::system_clock::now[chrono] chrono::seconds型 など[chrono] |
clock_gettime[time.h] |
C11の標準ヘッダthreads.hではtime.hをincludeすることが標準で要求される。
関連URL
- C11 <threads.h> emulation library, https://gist.github.com/yohhoy/2223710
- JTC1/SC22/WG21 N2985 C and C++ Thread Compatibility
- The Open Group Base Specifications Issue 7, IEEE Std 1003.1-2008 pthread.h, nanosleep, sched_yield