知識マップ: マルチスレッドの実務ベストプラクティス C言語編 ── Win32 APIの流儀で安全に書く
記事「マルチスレッドの実務ベストプラクティス C言語編 ── Win32 APIの流儀で安全に書く」の主張を、概念と関係(エッジ)に分解した知識グラフの全体です。各関係には根拠・確認日・確度が付いています。
Cではロックの解放を保証する言語機構がないため、原則を規律として明文化する必要があります。スレッド作成はCRTのスレッドごとデータを初期化する_beginthreadexが一択で、CreateThreadで作ったスレッドがCRTを呼ぶとメモリ不足時にプロセスが終了させられることがあります。短命な仕事はWindowsスレッドプールへ委譲します。プロセス内のロックはSRWロックが既定で、再帰取得が必要なときだけCRITICAL_SECTION、常にカーネル遷移を伴うMutexをプロセス内の排他に使うのはよくある間違いです。単一変数の更新はInterlocked関数で行い、対象は自然な境界に整列している必要があります。待ち合わせは条件変数で、スプリアスウェイクアップがあるため目覚めたら条件を再確認します。TerminateThreadはロック・ヒープ・DLLの状態を壊すため使わず、停止イベントとWaitForMultipleObjectsによる協調停止を組みます。
flowchart LR
accTitle: C言語(Win32)のマルチスレッド設計ベストプラクティスの知識マップ
accDescr: CRTを呼ぶスレッドを_beginthreadexで作る理由、Windowsスレッドプールへの委譲、SRWロック・CRITICAL_SECTION・Mutexの使い分け、Interlockedと整列の前提、条件変数とスプリアスウェイクアップ、TerminateThreadが壊すものと停止イベントによる協調停止、DllMainのローダーロックを示す図
shared_mutable_state["共有可変状態"]
race_condition["競合状態(race condition)"]
createthread_api["CreateThread"]
c_runtime_library["CRT(Cランタイムライブラリ)"]
beginthreadex["_beginthreadex"]
windows_thread_pool["Windowsスレッドプール"]
terminatethread["TerminateThread"]
backpressure["backpressure"]
srw_lock["SRWロック(Slim Reader/Writer Lock)"]
in_process_mutual_exclusion["プロセス内の相互排他"]
critical_section["CRITICAL_SECTION"]
win32_mutex_object["Win32のMutexオブジェクト"]
interlocked_functions["Interlocked関数"]
variable_alignment["変数の整列(アラインメント)"]
volatile_keyword["volatile"]
thread_local_state["スレッドローカル状態"]
win32_condition_variable["Win32の条件変数"]
spurious_wakeup["スプリアスウェイクアップ"]
bounded_buffer["有限バッファー"]
polling_wait["ポーリングによる待機"]
deadlock["デッドロック(deadlock)"]
stop_event_pattern["停止イベント+WaitForMultipleObjects"]
cooperative_cancellation["協調キャンセル"]
lock_ordering["ロック取得順序の統一"]
dllmain_loader_lock["DllMainとローダーロック"]
c11_threads["C11スレッド(<threads.h>)"]
windows_only_codebase["Windows専用のコードベース"]
shared_mutable_state -->|"原因になり得る"| race_condition
createthread_api -->|"両立しない"| c_runtime_library
beginthreadex -->|"実装を担う"| c_runtime_library
windows_thread_pool -.->|"の後継"| createthread_api
windows_thread_pool -->|"両立しない"| terminatethread
windows_thread_pool -.->|"前提とする"| backpressure
srw_lock -->|"推奨される対応"| in_process_mutual_exclusion
critical_section -.->|"推奨される対応"| in_process_mutual_exclusion
win32_mutex_object -->|"用いるのは非推奨"| in_process_mutual_exclusion
interlocked_functions -->|"防止する"| race_condition
interlocked_functions -->|"前提とする"| variable_alignment
volatile_keyword -->|"用いるのは非推奨"| race_condition
thread_local_state -.->|"軽減する"| shared_mutable_state
win32_condition_variable -->|"利用する"| critical_section
win32_condition_variable -->|"原因になり得る"| spurious_wakeup
bounded_buffer -->|"実装を担う"| backpressure
win32_condition_variable -->|"の後継"| polling_wait
terminatethread -->|"原因になり得る"| deadlock
stop_event_pattern -->|"の後継"| terminatethread
stop_event_pattern -->|"実装を担う"| cooperative_cancellation
lock_ordering -->|"防止する"| deadlock
dllmain_loader_lock -->|"原因になり得る"| deadlock
c11_threads -.->|"用いるのは非推奨"| windows_only_codebase
概念間の関係(全23件)
図と同じ関係を文章でも列挙します。表示している文と機械可読な意味データ(RDFa)は同じ要素に載っています。確度が「確立した関係」のものは直接の関係として、「条件付きの関係」のものは成立条件つきの言明(rdf:Statement)として表現しています。
- 共有可変状態は競合状態(race condition)の原因になることがあります。
- CreateThreadはCRT(Cランタイムライブラリ)と両立しません。
- _beginthreadexはCRT(Cランタイムライブラリ)の実装を担います。
- WindowsスレッドプールはCreateThreadの後継に当たります。
- WindowsスレッドプールはTerminateThreadと両立しません。
- Windowsスレッドプールはbackpressureを前提とします。
- SRWロック(Slim Reader/Writer Lock)はプロセス内の相互排他に対する本記事の推奨です。
- CRITICAL_SECTIONはプロセス内の相互排他に対する本記事の推奨です。
- Win32のMutexオブジェクトをプロセス内の相互排他に用いることは推奨されません。
- Interlocked関数は競合状態(race condition)を防ぎます。
- Interlocked関数は変数の整列(アラインメント)を前提とします。
- volatileを競合状態(race condition)に用いることは推奨されません。
- スレッドローカル状態は共有可変状態を軽減します。
- Win32の条件変数はCRITICAL_SECTIONを利用します。
- Win32の条件変数はスプリアスウェイクアップの原因になることがあります。
- 有限バッファーはbackpressureの実装を担います。
- Win32の条件変数はポーリングによる待機の後継に当たります。
- TerminateThreadはデッドロック(deadlock)の原因になることがあります。
- 停止イベント+WaitForMultipleObjectsはTerminateThreadの後継に当たります。
- 停止イベント+WaitForMultipleObjectsは協調キャンセルの実装を担います。
- ロック取得順序の統一はデッドロック(deadlock)を防ぎます。
- DllMainとローダーロックはデッドロック(deadlock)の原因になることがあります。
- C11スレッド(<threads.h>)をWindows専用のコードベースに用いることは推奨されません。
主要概念の定義
機械可読データ
このデータセットについて
このページはサイトの知識グラフ(_data/knowledge/)から自動生成されています。誤りの指摘はお問い合わせからお願いします。