基本情報技術者 2010年 春期 午前(科目A) 問08
問題文
あるプログラム A の処理が終了していないときに、別のプログラムから再度呼び出されても正しく動作するとき、このプログラム A の性質を何と呼ぶか。
選択肢
ア:再帰的
イ:再使用可能
ウ:再入可能(正解)
エ:再配置可能
🔒 解説は解答すると表示されます
再入可能性(再入可能関数)【午前解説】
正解の理由
「処理が終了していないときに別のプログラムから再度呼び出されても正しく動作する」という定義は、関数やルーチンが中断されても再び入口から呼ばれても安全に動作する性質を指します。これが「再入可能(reentrant)」です。再入可能であれば、同一コードが複数の実行経路(割込み、シグナルハンドラ、別スレッドなど)から並行して呼ばれても、共有の破壊的な副作用が発生しません。したがって正解は ウ です。
解法ステップ
- 問題文のキーワードを確認:「処理が終了していないときに別のプログラムから再度呼び出されても正しく動作」→同時・中断後再呼出しに耐える性質。
- 各選択肢の定義を照合する:再帰的=自己呼び出し可能、再使用可能=再利用できる設計、再配置可能=メモリ配置の自由度、再入可能=中断・再呼出しに耐える。
- 最も定義に合致するものを選ぶ → 再入可能(ウ)。
選択肢別の誤答解説
- ア: 再帰的
- 間違い。再帰的は関数が自分自身を呼ぶ能力を示すのみで、割込みや並行呼び出しへの安全性を表しません。
- イ: 再使用可能
- 間違い。再使用可能はコンポーネントを繰り返し使えることを指し、同時実行や中断後の安全性とは別概念です。
- ウ: 再入可能
- 正解。割込みや別スレッドなどで元の処理が終わっていなくても、再度呼ばれても正しく動作する性質を示します。
- エ: 再配置可能
- 間違い。再配置可能(relocatable)はプログラムやコードを別のメモリ位置に置ける性質で、呼び出しの同時性とは無関係です。
よくある誤解
- 「再帰的(ア)」と混同する:再帰的は自己呼び出し可能という意味で、同時実行や割込みに対する安全性とは別概念です。
- 「スレッドセーフ=再入可能」と誤解する:スレッドセーフはロックなどで並列実行を制御することが多く、ロックによる待ちやデッドロックがあると再入可能ではない場合があります。
- グローバル変数を読んでいるだけなら安全と考える誤り:読み取りでも他で更新されうる場合は問題になるため、本当に不変かを確認する必要があります。
補足コラム
- 実用例:C 標準ライブラリの strtok は非再入可能(内部静的状態を使う)で、スレッドやシグナルハンドラでの再入を避ける必要があります。代わりに strtok_r(POSIX)や strtok_s(Windows)といった再入可能版が提供されています。
- シグナルハンドラ内で呼ぶべき関数は再入可能でなければなりません。POSIX では "async-signal-safe" 関数の一覧が指定されています。
- 再入可能にするには、共有状態を排除する、状態を呼び出し側で持たせる、ローカル変数のみを使う、あるいはスレッド局所ストレージ(TLS)を使うなどの手法があります。
コード例(C):非再入可能な例と再入可能に直した例
/* 非再入可能: 静的バッファを使う */
char *my_strdup(const char *s) {
static char buf[256]; // 共有の静的バッファ -> 再入不可
strncpy(buf, s, sizeof(buf)-1);
buf[sizeof(buf)-1] = '\0';
return buf;
}
/* 再入可能: 呼び出し側が領域を渡す */
char *my_strdup_r(const char *s, char *buf, size_t bufsize) {
strncpy(buf, s, bufsize-1);
buf[bufsize-1] = '\0';
return buf;
}
FAQ
Q1: 再入可能とスレッドセーフは同じですか?
A1: 厳密には異なります。再入可能は中断や再呼出しに耐えることを意味し、スレッドセーフは複数スレッドから安全に使えることを指します。ロックを使うスレッドセーフな実装は再入可能でない場合があります。
A1: 厳密には異なります。再入可能は中断や再呼出しに耐えることを意味し、スレッドセーフは複数スレッドから安全に使えることを指します。ロックを使うスレッドセーフな実装は再入可能でない場合があります。
Q2: 再入可能にする簡単な方法は?
A2: 共有の可変データを排除し、必要な状態は呼び出し側で管理させるか局所変数やスレッド局所ストレージを使います。
A2: 共有の可変データを排除し、必要な状態は呼び出し側で管理させるか局所変数やスレッド局所ストレージを使います。
Q3: テスト方法は?
A3: 割込みやシグナル、別スレッドから同時に呼び出すストレステストを行い、共有状態の競合や破壊が起きないか確認します。ツールや静的解析も有効です。
A3: 割込みやシグナル、別スレッドから同時に呼び出すストレステストを行い、共有状態の競合や破壊が起きないか確認します。ツールや静的解析も有効です。
関連キーワード: 再入可能, 再帰, スレッドセーフ, strtok, シグナルハンドラ, 再配置可能, 再使用可能, 再入性テスト

\ せっかくなら /
基本情報技術者を
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

