# 画面設計書 36-スレッド

## 概要

libuvユーザーガイドのスレッドページ（guide/threads.rst）に関する画面設計書。スレッド操作、同期プリミティブ、ワークキュー、スレッド間通信の使い方をサンプルコード付きで解説するページの構造と仕様を定義する。

### 本画面の処理概要

本ページはlibuvのスレッド機能全般を解説するガイドページである。スレッド作成・結合、同期プリミティブ（ミューテックス、読み書きロック、セマフォ、条件変数、バリア、ワンスガード、TLS）、ワークキュー（uv_queue_work）、およびスレッド間通信（uv_async_send）を網羅的にカバーする。

**業務上の目的・背景**：イベントループとスレッドの関係を正しく理解することは、libuvプログラミングにおいて極めて重要である。本ページでは「イベントループは1つ、メインスレッドで実行」という前提を明示し、ブロッキング処理をスレッドプールで実行する方法（uv_queue_work）と、スレッドからイベントループに通知を送る方法（uv_async_send）を解説する。これにより、サードパーティのブロッキングライブラリをイベントループパラダイムに統合する実践的なパターンが学べる。

**画面へのアクセス方法**：ユーザーガイド一覧（No.31）のtoctreeリンク、またはネットワーク（No.35）からのNextナビゲーションでアクセスする。URLパスは `/guide/threads.html` となる。

**主要な操作・処理内容**：
1. スレッドとイベントループの関係の解説
2. コアスレッド操作（thread-create/main.c）の表示と解説
3. 同期プリミティブ（ミューテックス、読み書きロック等）の解説
4. 読み書きロックサンプル（locks/main.c）の表示と解説
5. ワークキュー（queue-work/main.c、queue-cancel/main.c）の表示と解説
6. uv_cancel()によるタスクキャンセルの解説
7. スレッド間通信（progress/main.c）の表示と解説 -- uv_async_send

**画面遷移**：
- 遷移元：ユーザーガイド一覧（No.31）、ネットワーク（No.35）
- 遷移先：プロセス（No.37）
- 内部参照：`_inter-thread-communication` ラベル、`_libuv-work-queue` ラベル
- 外部リンク：pthreads manページ、セマフォ/条件変数/バリアのWikipedia、TLS API

**権限による表示制御**：なし。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 125 | スレッド作成 | 主機能 | uv_thread_create()を使ったスレッド作成のサンプル解説 |
| 126 | スレッド結合・分離 | 主機能 | uv_thread_join()を使ったスレッド結合の使用例 |
| 124 | ワークキュー投入 | 主機能 | uv_queue_work()によるスレッドプール活用のサンプル解説 |
| 132 | ミューテックス | 補助機能 | ミューテックスによる排他制御のサンプル解説 |
| 136 | バリア | 補助機能 | バリア同期のサンプル解説 |

## 画面種別

チュートリアル（サンプルコード付き解説）

## URL/ルーティング

- ソースファイル：`docs/src/guide/threads.rst`
- 生成先URL：`/guide/threads.html`
- Sphinxルーティング：guide.rstのtoctreeから参照

## 入出力項目

| 項目名 | 入出力 | 型 | 説明 |
|--------|--------|-----|------|
| スレッド概要 | 出力 | テキスト | スレッドとイベントループの関係 |
| thread-create/main.cコード | 出力 | Cソースコード | スレッド作成サンプル（部分表示） |
| ミューテックス関数一覧 | 出力 | Cコードブロック | uv_mutex_*関数のプロトタイプ |
| locks/main.cコード | 出力 | Cソースコード | 読み書きロックサンプル（全体、ハイライト付き） |
| queue-work/main.cコード | 出力 | Cソースコード | ワークキューサンプル（部分表示） |
| queue-cancel/main.cコード | 出力 | Cソースコード | キャンセルサンプル（部分表示、ハイライト付き） |
| progress/main.cコード | 出力 | Cソースコード | スレッド間通信サンプル（部分表示、ハイライト付き） |
| uv_once使用例 | 出力 | Cコードブロック | ワンスガードの使用例（インラインコード） |

## 表示項目

| 項目名 | 表示内容 | 備考 |
|--------|----------|------|
| セクションタイトル | "Threads" | ページ見出し（h1） |
| Core thread operations (h2) | uv_thread_create/join | thread-create/main.c参照 |
| Synchronization Primitives (h2) | 同期プリミティブの概要 | |
| Mutexes (h3) | ミューテックスAPI一覧と注意事項 | デバッグモードでのabort挙動 |
| Locks (h3) | 読み書きロック | locks/main.c参照 |
| Others (h3) | セマフォ/条件変数/バリア/ワンスガード/TLS | |
| libuv work queue (h2) | uv_queue_work解説 | queue-work/main.c参照 |
| Inter-thread communication (h2) | uv_async_send解説 | progress/main.c参照 |
| TIPボックス | uv_thread_tはpthread_tのエイリアス | 実装詳細の注意 |
| WARNINGボックス | uv_async_sendの非同期性に関する重要な注意 | コールバック呼び出し保証 |
| TIPボックス | 長時間実行ワーカーの終了方法 | 変数による通知パターン |
| NOTEボックス | mutex/rwlockはシグナルハンドラ内では使用不可 | uv_async_sendは使用可能 |
| NOTEボックス | Windowsのミューテックスは常に再帰的 | プラットフォーム差異 |

## イベント仕様

### 1-ワークキューの処理フロー

queue-work/main.cで示されるパターン：
1. uv_queue_work(loop, &req, work_cb, after_work_cb) -- ワーク投入
2. work_cb -- 別スレッドで実行（fibonacciの計算）
3. after_work_cb -- メインスレッドで実行（完了通知）

### 2-スレッド間通信の処理フロー

progress/main.cで示されるパターン：
1. uv_async_init(loop, &async, print_progress) -- 非同期ハンドル初期化
2. uv_thread_create -- ワーカースレッド起動
3. uv_async_send(&async) -- ワーカーからの通知送信
4. print_progress() -- メインスレッドのコールバック

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| - | - | - | 静的HTMLページのため該当なし |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|---------|
| T-36-01 | ヒント | "uv_thread_t is just an alias for pthread_t on Unix..." | Core thread operations |
| W-36-01 | 警告 | "It is important to realize that since the message send is async..." | Inter-thread communication |
| T-36-02 | ヒント | "A well designed program would have a way to terminate long running workers..." | libuv work queue |
| N-36-01 | 注記 | "mutexes and rwlocks DO NOT work inside a signal handler..." | Inter-thread communication末尾 |
| N-36-02 | 注記 | "Mutexes on Windows are always recursive." | Mutexesセクション |

## 例外処理

静的HTMLページのため、アプリケーションレベルの例外処理は発生しない。

## 備考

- 本ページの前提：「イベントループは1つ、メインスレッドで実行。他のスレッドはuv_async_send以外でイベントループと相互作用しない」
- uv_thread_joinはpthread_joinと異なり、スレッドから値を受け取ることができない。
- uv_cancel()はキュー投入済みだが未開始のタスクのみキャンセル可能。実行中のタスクはキャンセルできない。
- uv_async_sendのコールバックは「少なくとも1回」呼ばれることが保証される。複数のsendが1回のコールバックにまとめられる可能性がある。
- Node.jsにおけるv8スレッドアフィニティとuv_async_sendの組み合わせパターンが解説されている。

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

スレッド関連の型とワークキューの構造体を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | threads.rst | `docs/src/guide/threads.rst` | 行1-30: スレッドとイベントループの関係、前提条件の把握 |
| 1-2 | thread-create/main.c | `docs/code/thread-create/main.c` | 行1-4: uv_thread_t型の使用方法 |
| 1-3 | queue-work/main.c | `docs/code/queue-work/main.c` | 行7-8: uv_work_t型とデータ渡しパターン |

**読解のコツ**: uv_thread_tはUnixではpthread_tのエイリアスだが、クロスプラットフォーム互換性のためuv_thread_*関数を使用すべきである。uv_work_tのvoid* dataフィールドがスレッド間のデータ受け渡しの主要手段。

#### Step 2: スレッド作成・結合の基本を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | thread-create/main.c | `docs/code/thread-create/main.c` | 行25-35: main関数 -- 2つのスレッド作成とjoin |
| 2-2 | thread-create/main.c | `docs/code/thread-create/main.c` | 行5-13: hare/tortoise関数 -- スレッドエントリーポイント |

**主要処理フロー**:
1. **行29**: `uv_thread_create(&hare_id, hare, &tracklen)` -- スレッド作成
2. **行30**: `uv_thread_create(&tortoise_id, tortoise, &tracklen)` -- スレッド作成
3. **行32**: `uv_thread_join(&hare_id)` -- スレッド結合待ち
4. **行33**: `uv_thread_join(&tortoise_id)` -- スレッド結合待ち

#### Step 3: ワークキューの処理フローを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | queue-work/main.c | `docs/code/queue-work/main.c` | 行31-44: main関数 -- 25個のfibonacciワーク投入 |
| 3-2 | queue-work/main.c | `docs/code/queue-work/main.c` | 行17-25: fib関数 -- ワーカースレッドで実行 |
| 3-3 | queue-work/main.c | `docs/code/queue-work/main.c` | 行27-29: after_fib関数 -- メインスレッドで完了通知 |

**主要処理フロー**:
1. **行40**: `uv_queue_work(loop, &req[i], fib, after_fib)` -- ワーク投入
2. **行17-25**: `fib()` -- 別スレッドで実行（sleep + fibonacci計算）
3. **行27-29**: `after_fib()` -- メインスレッドで完了コールバック

### プログラム呼び出し階層図

```
thread-create/main.c
    |
    +-- uv_thread_create(&hare_id, hare, &tracklen)
    |       +-- hare() [別スレッド実行]
    +-- uv_thread_create(&tortoise_id, tortoise, &tracklen)
    |       +-- tortoise() [別スレッド実行]
    +-- uv_thread_join(&hare_id)
    +-- uv_thread_join(&tortoise_id)

queue-work/main.c
    |
    +-- uv_queue_work(loop, &req[i], fib, after_fib) x25
    |       +-- fib() [スレッドプールで実行]
    |       +-- after_fib() [メインスレッドで実行]
    +-- uv_run(loop, UV_RUN_DEFAULT)

progress/main.c
    |
    +-- uv_async_init(loop, &async, print_progress)
    +-- uv_thread_create(&tid, fake_download, &async)
    |       +-- fake_download() [別スレッド]
    |               +-- uv_async_send(&async) [複数回]
    |                       +-- print_progress() [メインスレッド、コールバック]
    +-- uv_run(loop, UV_RUN_DEFAULT)
```

### データフロー図

```
[入力]                        [処理]                         [出力]

データ (void* data)       --> uv_queue_work()             --> スレッドプールで実行
ワーク完了                --> after_work_cb()              --> メインスレッドで通知
進捗データ (data field)   --> uv_async_send()              --> メインスレッドのコールバック
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| threads.rst | `docs/src/guide/threads.rst` | テンプレート | スレッドガイドページ本体 |
| guide.rst | `docs/src/guide.rst` | テンプレート | 親ページ（toctreeで参照） |
| thread-create/main.c | `docs/code/thread-create/main.c` | ソース | スレッド作成サンプル |
| locks/main.c | `docs/code/locks/main.c` | ソース | 読み書きロックサンプル |
| queue-work/main.c | `docs/code/queue-work/main.c` | ソース | ワークキューサンプル |
| queue-cancel/main.c | `docs/code/queue-cancel/main.c` | ソース | ワークキャンセルサンプル |
| progress/main.c | `docs/code/progress/main.c` | ソース | スレッド間通信サンプル |
| conf.py | `docs/src/conf.py` | 設定 | Sphinxビルド設定 |
