スレッドセーフスレッドセーフ(英: thread-safe)は、マルチスレッドプログラミングにおける概念である。あるプログラムコードがスレッドセーフであるという場合、そのコードを複数のスレッドが同時並行的に実行しても問題が発生しないことを意味する[1]。特に、ある共有データへの複数のスレッドによる読み書きアクセスがあるとき、一度に1つのスレッドのみがその共有データにアクセスするようにして安全性を確保しなければならない。スレッドセーフでないコードを同時並行的に実行すると、データ競合による未定義動作を引き起こしたり、競合状態(レースコンディション)による意図しない動作を引き起こしたりする。場合によっては深刻なセキュリティホール(脆弱性)が引き起こされることもある[2]。 概要スレッドセーフはマルチスレッドプログラミングにおける重要な要素である。それは従来、オペレーティングシステムの開発者だけが考慮しなければならない問題だったが、1990年代後半には一般的な問題となった[注釈 1]。マルチスレッドプログラムでは、複数のスレッドが同じアドレス空間内で同時に実行される。各スレッドのアクセスするメモリ領域が特に制限されることはなく、全スレッドが全アドレス空間にアクセスできる。異なるスレッドが同時に同じメモリ領域に読み取りアクセスする場合は問題にならないが、異なるスレッドが同時に同じメモリ領域に読み書きアクセスする場合(少なくともどちらか一方のスレッドが書き込みアクセスする場合)は競合の問題が発生しうる。また、スレッドがどのような順番で実行され、データアクセスがどのような順序で発生するかは、オペレーティングシステムのスケジューリング仕様や、実行時の計算資源の利用状況などといった外因次第であり、完全に予期・予測することはできず非決定論的な動作をする。従って、静的コード解析だけでスレッドに関するプログラム上の誤りを見つけるのは困難となる。マルチスレッド環境では、そのような理論上起こりうる状況を考慮し、調停のための排他制御をするなど、慎重なプログラミングが求められる。 データ競合のようなスレッドに関する誤りを含むプログラムは、前述のように異常動作や誤動作を引き起こしうる。スレッドセーフとは、そのような意図しない動作を発生させないことを保証するための、コード実行の安全性に関わる指標である。 しかし、ある操作をスレッドセーフにするためには相応の時間的・空間的オーバーヘッドを伴うため、プログラム上のありとあらゆる操作をスレッドセーフにしようとすることは現実的ではない。不必要な排他制御はプログラムのパフォーマンス低下を招く[4]。例えば単一のスレッドからしかアクセスされないことが分かりきっているデータ領域へのアクセスや、すべてのスレッドから読み取りアクセスのみされる完全定数データ領域へのアクセスを排他制御しようとするのは完全に無駄である。そのため、実際に複数のスレッドによって同時に読み書きアクセスが実行されうるコード領域(危険領域、クリティカルセクション)に関してのみスレッドセーフ化する。 スレッドセーフかどうかの判断基準あるコードの断片がスレッドセーフかどうかを判断するのは簡単ではない。しかし、以下のような点に注意して調べることで問題が見つかることが多い。
スタック上の変数のみを使用し、引数にのみ依存し、同様な特性のサブルーチンしか呼ばないならば、そのサブルーチンはリエントラントであり、スレッドセーフである。このようなサブルーチンは「純関数; pure function」などと呼ばれることもあり、数学の関数によく似ている。 静的コード解析ツールの中には、プログラムの並行性に関するバグをある程度検出してくれるものもあり、スレッドセーフでないコードに対して警告を出す[5]。 スレッドセーフの実現手法スレッドセーフを実現する方法として以下のようなものがある。
一般的にはこれらの手法に以下の手法を結合して使用する。
なお、ファイルのようなシステム共有リソースに関しては、同じプロセス内で動作する他のスレッドだけでなく、別のプロセス内で動作する他のスレッドからもアクセスされる可能性がある。そのため、場合によっては単にスレッドセーフにするだけでは不十分であり、必要に応じてプロセス間で排他制御する(ファイルロックも参照)。 脚注注釈
出典
関連項目外部リンク
以下、英文
|
Portal di Ensiklopedia Dunia