# 画面設計書 37-プロセス

## 概要

libuvユーザーガイドのプロセスページ（guide/processes.rst）に関する画面設計書。子プロセス生成、プロセスパラメータ変更、シグナル処理、子プロセスI/O、親子IPC、ファイルディスクリプタ送信の使い方をサンプルコード付きで解説するページの構造と仕様を定義する。

### 本画面の処理概要

本ページはlibuvの子プロセス管理機能を網羅的に解説するガイドページである。uv_spawn()による子プロセス生成から、プロセスオプション設定、デタッチ、シグナル送信、stdio継承、パイプによる親子IPC、ファイルディスクリプタ転送によるロードバランシングまで、段階的に高度な内容をカバーする。

**業務上の目的・背景**：マルチプロセスモデルはマルチコアCPU活用やサービス分離において重要なアーキテクチャパターンである。本ページでは、単純なプロセス起動から始めて、CGIサーバーの実装（子プロセスのstdoutをTCPソケットに接続）、さらにはワーカープロセスへのファイルディスクリプタ送信によるロードバランシングサーバー（multi-echo-server）まで、実践的なパターンを段階的に解説する。シグナル処理についても複数イベントループでの使用例が含まれる。

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

**主要な操作・処理内容**：
1. 子プロセス生成（spawn/main.c）の表示と解説
2. プロセスパラメータ変更（cwd、env、flags、UID/GID）の説明
3. プロセスデタッチ（detach/main.c）の表示と解説
4. シグナル送信（uv_process_kill / uv_kill）の説明
5. シグナルハンドリング（signal/main.c）の表示と解説
6. 子プロセスI/O（proc-streams/main.c）-- stdio継承の表示と解説
7. CGIサーバー（cgi/main.c）-- ストリーム継承の表示と解説
8. 親子IPC（pipe-echo-server/main.c）-- ドメインソケット使用の表示と解説
9. ファイルディスクリプタ転送（multi-echo-server/main.c + worker.c）-- ロードバランシングの表示と解説

**画面遷移**：
- 遷移元：ユーザーガイド一覧（No.31）、スレッド（No.36）
- 遷移先：イベントループ応用（No.38）、ネットワーク（No.35、:doc:networkingへの参照）
- 外部リンク：execvp manページ、CGI Wikipedia、D-BUS、socat、Named Pipe (Windows)

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 90 | プロセス生成 | 主機能 | uv_spawn()による子プロセス生成のサンプル解説 |
| 91 | プロセスキル | 補助機能 | プロセスへのシグナル送信の使用例 |
| 93 | シグナルハンドル初期化 | 補助機能 | シグナルハンドリングのサンプル解説 |
| 94 | シグナル監視開始 | 補助機能 | シグナル監視の使用例 |

## 画面種別

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

## URL/ルーティング

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

## 入出力項目

| 項目名 | 入出力 | 型 | 説明 |
|--------|--------|-----|------|
| プロセス概要 | 出力 | テキスト | マルチプロセスモデルの利点の説明 |
| spawn/main.cコード | 出力 | Cソースコード | 子プロセス生成サンプル（部分表示、ハイライト付き） |
| detach/main.cコード | 出力 | Cソースコード | デタッチサンプル（部分表示、ハイライト付き） |
| signal/main.cコード | 出力 | Cソースコード | シグナルハンドリングサンプル（ハイライト付き） |
| proc-streams/test.c | 出力 | Cソースコード | テストプログラム |
| proc-streams/main.cコード | 出力 | Cソースコード | stdio継承サンプル（部分表示、ハイライト付き） |
| cgi/tick.c | 出力 | Cソースコード | CGIスクリプト |
| cgi/main.cコード | 出力 | Cソースコード | CGIサーバーサンプル（部分表示、ハイライト付き） |
| pipe-echo-server/main.cコード | 出力 | Cソースコード | パイプエコーサーバー（部分表示、ハイライト付き） |
| multi-echo-server/main.cコード | 出力 | Cソースコード | マルチプロセスエコーサーバー（部分表示、ハイライト付き） |
| multi-echo-server/worker.cコード | 出力 | Cソースコード | ワーカープロセス（部分表示、ハイライト付き） |
| uv_stdio_container_t定義 | 出力 | Cコードブロック | stdio設定構造体の定義 |

## 表示項目

| 項目名 | 表示内容 | 備考 |
|--------|----------|------|
| セクションタイトル | "Processes" | ページ見出し（h1） |
| Spawning child processes (h2) | uv_spawn()の基本使用法 | spawn/main.c |
| Changing process parameters (h2) | cwd/env/flags設定 | |
| Change execution directory (h3) | cwdの設定方法 | |
| Set environment variables (h3) | env配列の設定方法 | |
| Option flags (h3) | UV_PROCESS_SETUID/SETGID/DETACHED等 | |
| Detaching processes (h2) | プロセスデタッチ | detach/main.c |
| Sending signals to processes (h2) | uv_kill/uv_process_kill | |
| Signals (h2) | uv_signal_tの使用法 | signal/main.c |
| Child Process I/O (h2) | stdio継承の設定 | proc-streams/main.c |
| Parent-child IPC (h2) | パイプによるIPC | pipe-echo-server/main.c |
| New stdio Pipes (h3) | UV_CREATE_PIPEフラグ | |
| Arbitrary process IPC (h3) | ドメインソケットによるIPC | pipe-echo-server/main.c |
| Sending file descriptors over pipes (h3) | FD転送によるロードバランシング | multi-echo-server |
| NOTEボックス | uv_process_options_tのゼロ初期化 | グローバル変数の暗黙的初期化 |
| NOTEボックス | UV_RUN_NOWAITとUV_RUN_ONCEの違い | signalサンプル内 |

## イベント仕様

### 1-子プロセス生成の処理フロー

spawn/main.cで示されるパターン：
1. uv_process_options_t構造体にfile/args/exit_cbを設定
2. uv_spawn(loop, &child_req, &options) -- 子プロセス起動
3. on_exit() -- 子プロセス終了時にexit_status/term_signalを受信
4. uv_close() -- ハンドルクローズ

### 2-シグナルハンドリングのパターン

signal/main.cで示されるパターン：
1. uv_signal_init(loop, &sig) -- シグナルハンドル初期化
2. uv_signal_start(&sig, handler, SIGUSR1) -- シグナル監視開始
3. signal_handler() -- シグナル受信時コールバック
4. uv_signal_stop() -- 監視停止

### 3-ファイルディスクリプタ転送パターン

multi-echo-serverで示されるパターン：
1. 親プロセスでTCPサーバーを起動
2. ワーカープロセスをCPU数分起動（UV_CREATE_PIPEでstdin接続）
3. 新規接続をuv_write2()でワーカーに転送（ラウンドロビン）
4. ワーカーはuv_pipe_pending_count()/uv_accept()でFDを受信

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

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

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

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|---------|
| N-37-01 | 注記 | "options is implicitly initialized with zeros since it is a global variable..." | Spawningセクション |
| N-37-02 | 注記 | "uv_run(loop, UV_RUN_NOWAIT) is similar to uv_run(loop, UV_RUN_ONCE)..." | Signalsセクション |

## 例外処理

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

## 備考

- UV_PROCESS_SETUID/SETGIDはUnixのみサポート。WindowsではUV_ENOTSUPエラーとなる。
- UV_PROCESS_DETACHEDフラグでデーモンプロセスを起動する場合、uv_unref()と組み合わせて「fire-and-forget」パターンを実現できる。
- uv_close()はexit callbackの後に呼ぶ必要がある。exit callback前に呼ぶと問題が発生する。
- multi-echo-serverサンプルはuv_cpu_info()を使用してCPU数に等しいワーカー数を起動する。
- uv_write2()でFD送信する際、空でないバッファが必要（Kyleの指摘による）。
- 脚注としてドメインソケットはWindowsの名前付きパイプに相当する旨が記載されている。

---

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

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

### 推奨読解順序

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

uv_process_tハンドルとuv_process_options_t構造体、uv_stdio_container_t構造体を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | processes.rst | `docs/src/guide/processes.rst` | 行43-48: uv_process_options_tのfile/argsフィールド |
| 1-2 | processes.rst | `docs/src/guide/processes.rst` | 行190-199: uv_stdio_container_t構造体の定義 |
| 1-3 | spawn/main.c | `docs/code/spawn/main.c` | 行6-8: グローバル変数（uv_process_t, uv_process_options_t） |

**読解のコツ**: uv_process_options_tのフィールドは多岐にわたるが、最低限file/args/exit_cbの3つを設定すればプロセスを起動できる。stdio設定はstdio_count/stdioフィールドで制御する。

#### Step 2: 子プロセス生成の基本パターンを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | spawn/main.c | `docs/code/spawn/main.c` | 行15-36: main関数 -- options設定とuv_spawn呼び出し |
| 2-2 | spawn/main.c | `docs/code/spawn/main.c` | 行10-13: on_exit コールバック -- 終了処理とuv_close |

**主要処理フロー**:
1. **行18-21**: argsの配列設定（"mkdir", "test-dir", NULL）
2. **行23-25**: optionsにexit_cb/file/argsを設定
3. **行28**: `uv_spawn(loop, &child_req, &options)` -- 子プロセス起動
4. **行32**: `child_req.pid` -- 起動されたプロセスのPID取得
5. **行10-12**: `on_exit` -- exit_statusとterm_signalを受信し、uv_closeでハンドルクローズ

#### Step 3: シグナルハンドリングを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | signal/main.c | `docs/code/signal/main.c` | 行54-66: main関数 -- 2つのスレッドで複数ループ起動 |
| 3-2 | signal/main.c | `docs/code/signal/main.c` | 行22-34: thread1_worker -- 1ループ内2つのシグナルハンドラ |
| 3-3 | signal/main.c | `docs/code/signal/main.c` | 行37-52: thread2_worker -- 2ループ各1つのシグナルハンドラ |
| 3-4 | signal/main.c | `docs/code/signal/main.c` | 行15-19: signal_handler -- シグナル受信とuv_signal_stop |

**主要処理フロー**:
1. **行27-28**: `uv_signal_init / uv_signal_start(&sig1a, signal_handler, SIGUSR1)` -- シグナルハンドラ登録
2. **行50**: `uv_run(loop2, UV_RUN_NOWAIT) || uv_run(loop3, UV_RUN_NOWAIT)` -- 2ループの並行実行
3. **行17-18**: `signal_handler` -- シグナル受信し、uv_signal_stopで停止

#### Step 4: マルチプロセスエコーサーバーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | multi-echo-server/main.c | `docs/code/multi-echo-server/main.c` | ワーカー起動とFD転送 |
| 4-2 | multi-echo-server/worker.c | `docs/code/multi-echo-server/worker.c` | FD受信とエコー処理 |

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

```
spawn/main.c
    |
    +-- uv_spawn(loop, &child_req, &options)
    |       +-- on_exit() [子プロセス終了時]
    |               +-- uv_close(&child_req)
    +-- uv_run(loop, UV_RUN_DEFAULT)

multi-echo-server/main.c (親)
    |
    +-- uv_tcp_init() / uv_tcp_bind() / uv_listen()
    +-- setup_workers() -- CPU数分のワーカー起動
    |       +-- uv_pipe_init(loop, &pipe, 1) [IPC=1]
    |       +-- uv_spawn(loop, &worker, &options) [stdin=pipe]
    +-- on_new_connection() [接続受入]
            +-- uv_accept(server, client)
            +-- uv_write2(pipe, buf, client) [FD転送]

multi-echo-server/worker.c (子)
    |
    +-- uv_pipe_init(loop, &queue, 1) [IPC=1]
    +-- uv_pipe_open(&queue, 0) [stdin接続]
    +-- uv_read_start(&queue, ..., on_new_connection)
            +-- uv_pipe_pending_count()
            +-- uv_accept(queue, client) [FD受信]
            +-- uv_read_start(client, ..., echo_read)
```

### データフロー図

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

options (file/args)        --> uv_spawn()                   --> 子プロセス (PID)
exit_status/term_signal    --> on_exit()                    --> ハンドルクローズ
クライアントFD (親)        --> uv_write2() [パイプ経由]     --> ワーカー受信
パイプ (stdin)             --> uv_accept() [ワーカー]       --> クライアントハンドル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| processes.rst | `docs/src/guide/processes.rst` | テンプレート | プロセスガイドページ本体 |
| guide.rst | `docs/src/guide.rst` | テンプレート | 親ページ |
| spawn/main.c | `docs/code/spawn/main.c` | ソース | 子プロセス生成サンプル |
| detach/main.c | `docs/code/detach/main.c` | ソース | デタッチサンプル |
| signal/main.c | `docs/code/signal/main.c` | ソース | シグナルハンドリングサンプル |
| proc-streams/main.c | `docs/code/proc-streams/main.c` | ソース | stdio継承サンプル |
| proc-streams/test.c | `docs/code/proc-streams/test.c` | ソース | テストプログラム |
| cgi/main.c | `docs/code/cgi/main.c` | ソース | CGIサーバーサンプル |
| cgi/tick.c | `docs/code/cgi/tick.c` | ソース | CGIスクリプト |
| pipe-echo-server/main.c | `docs/code/pipe-echo-server/main.c` | ソース | パイプエコーサーバー |
| multi-echo-server/main.c | `docs/code/multi-echo-server/main.c` | ソース | マルチプロセスサーバー（親） |
| multi-echo-server/worker.c | `docs/code/multi-echo-server/worker.c` | ソース | ワーカープロセス |
| conf.py | `docs/src/conf.py` | 設定 | Sphinxビルド設定 |
