リエントラント性とは
リエントラント性 (reentrancy) とは、プログラムや
サブルーチンが既に実行中に、外的要因により再び実行されても安全である性質を指します。この概念は、特に割り込み処理において重要です。割り込み処理が行われると、現在の実行を中断し、他の
サブルーチンやサービスルーチンを急遽実行することがあります。そのため、これらの
サブルーチンが自らを安全に呼び出すことができる必要があります。
割り込みとリエントラント性の関係
割り込みはハードウェアやソフトウェアのイベントによって発生し、プログラムの実行フローを変える可能性があります。そのため、
サブルーチンが、実行中の状態を保ちつつ割り込まれた際に安全に再度実行されることが求められるのです。
シングルスレッドとマルチスレッド環境
リエントラント性はもともとシングルスレッド環境から生まれた概念で、マルチスレッド環境においては
スレッドセーフという関連したが異なる考え方が存在します。
スレッドセーフなコードは、複数のスレッドが同時にアクセスしても問題が起きないことを指しますが、リエントラントである必要はありません。このため、コードがリエントラントであれば、同一スレッド内で
再帰的に呼び出されても問題ありません。しかし、必ずしも
スレッドセーフとは限りません。
リエントラントでないコードの問題
たとえば、
グローバル変数を変更する
サブルーチンはリエントラントではないとされます。なぜなら、
再帰的に呼び出された場合、同じ
グローバル変数に対して異なる値が代入され、期待しない動作を引き起こす可能性があるからです。逆に、
ローカル変数を使用し、引数としてデータを受け渡す関数は、
再帰的に呼ばれた際にも安全に動作することができます。
リエントラント性の原則
リエントラントなコードが満たすべき条件には以下のようなものがあります:
- - グローバル変数や静的変数を保持しないこと
- - 自身のコードを書き換えないこと
- - リエントラントでない関数を呼び出さないこと
これにより、アクセス時の競合状態を防ぎ、安全に再実行可能な状態を維持します。
リエントラントな割り込みハンドラ
特に、リエントラントな割り込みハンドラは、割り込み処理中でもなるべく早く他の割り込みを受け付けることができるように設計されています。これにより、割り込みレイテンシが低減され、システム全体の反応が改善されることが期待されます。
POSIX標準においては、特に「_r」接尾辞が付加された関数が存在し、これらはリエントラントとして設計されています。これにより、複数のスレッドから呼び出されても、呼び出しの実行順序が影響しないことが保証されています。さらに、
POSIXでは非同期シグナル安全な関数も定義しており、これらを適切に使うことで、シグナル処理中に安全に処理を行うことができます。
結論
リエントラント性は、割り込み処理や同時実行するプログラムにおいて重要な設計思想です。しかし、
グローバル変数を使用しているコードはリエントラントでない可能性が高く、開発者はいかにして適切なデータ管理と設計を行うかが問われます。最終的には、データの使い方やコードの設計が、安全で効率的なプログラミングを実現する鍵となります。