yohhoyの日記

2012-06-19

C11/C++11/POSIXスレッドAPI比較

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する必要のあるヘッダファイル。

C11C++11POSIX
スレッドthreads.hthreadpthreads.h
time.h
sched.h
CallOncethreads.hmutexpthreads.h
排他制御threads.hmutexpthreads.h
条件変数threads.hcondition_variablepthreads.h
TLS言語組込
threads.h
言語組込pthreads.h
その他-future-

C11におけるTLSは言語組み込み機能+標準ライブラリサポートで構成される。
C++11におけるTLSは言語組み込み機能のため、特定のヘッダincludeを必要としない。

スレッド

スレッドオブジェクトを表現する型と呼出可能な関数シグネチャ、スレッド作成/待機/比較といった操作を行う関数群。

C11C++11POSIX
thrd_t型threadクラスpthread_t型
int (*)(void*)任意の関数オブジェクトvoid* (*)(void*)
thrd_createthreadコンストラクタpthread_create
thrd_jointhread::joinpthread_join
thrd_detachthread::detachpthread_detach
thrd_exit関数オブジェクトからのreturnpthread_exit
thrd_currentthis_thread::get_idpthread_self
thrd_equalthread::get_id と
thread::id::operator=
pthread_equal
thrd_sleepthis_thread::sleep_for
this_thread::sleep_until
nanosleep[time.h]
thrd_yieldthis_thread::yieldsched_yield[sched.h]

C11およびPOSIXではスレッド作成(create)関数に指定したユーザ定義関数の戻り値を、該当スレッドに対する待機(join)関数の戻り値として取得できる。
C++11では別スレッドにて実行された関数オブジェクトの戻り値は破棄される。スレッド間での値受け渡しを実装するには、別途future/promiseクラス[標準ヘッダfuture]を利用する必要がある。(→id:yohhoy:20120131
スレッドキャンセル処理はPOSIXでのみ提供される。C11およびC++11において相当機能が必要な場合、条件変数等を用いて別途実装する必要がある。

CallOnce

CallOnce処理を実現するためのフラグ型と初期化定数、呼出可能な関数シグネチャとCallOnce関数。

C11C++11POSIX
once_flag型once_flag型pthread_once_t型
ONCE_FLAG_INITマクロ-PTHREAD_ONCE_INITマクロ
void (*)(void)任意の関数オブジェクトvoid (*)(void)
call_oncecall_oncepthread_once

C++11におけるフラグ型once_flagはconstexprなデフォルトコンストラクタを持つため、特に初期化定数を必要としない。

排他制御

ミューテックスオブジェクトを表現する型と、ミューテックスのロック獲得/開放といった操作を行う関数群。C++11列のMutexは具体的なクラス名ではなく、mutex, recursive_mutex, timed_mutex, recursive_timed_mutex のいずれかを表す*2

C11C++11POSIX
mtx_t型Mutexクラスpthread_mutex_t型
mtx_initMutexコンストラクタpthread_mutex_init
mtx_destroyMutexデストラクタpthread_mutex_destroy
mtx_lockMutex::lockpthread_mutex_lock
mtx_unlockMutex::unlockpthread_mutex_unlock
mtx_trylockMutex::try_lockpthread_mutex_trylock
mtx_timedlockMutex::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定数を指定する。


条件変数

条件変数オブジェクトを表現する型と、条件変数への通知/待機といった操作を行う関数群。

C11C++11POSIX
cnd_t型condition_variableクラスpthread_cond_t型
cnd_initcondition_variableコンストラクタpthread_cond_init
cnd_destroycondition_variableデストラクタpthread_cond_destroy
cnd_signalcondition_variable::notify_onepthread_cond_signal
cnd_broadcastcondition_variable::notify_allpthread_cond_broadcast
cnd_waitcondition_variable::waitpthread_cond_wait
cnd_timedwaitcondition_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値の設定/取得といった操作を行う関数群。

C11C++11POSIX
_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


その他

タイムアウト付き待機関数で利用する時刻/時間表現型と現在時刻取得関数。

C11C++11POSIX
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

*1:余談:C標準ライブラリでの偏執的な関数名の短さはどこから来るの…

*2:try_lock_for, try_lock_untilメンバ関数はtimed_mutexとrecursive_timed_mutexクラスにのみ存在。

*3:C11標準規格が許容するのは次の4種類:mtx_plain, mtx_timed, mtx_plain|mtx_recursive, mtx_timed|mtx_recursive

*4:参考実装:http://www.boost.org/boost/thread/barrier.hpp

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

リンク元