PHPのスレッドセーフ版(TS)とノンスレッドセーフ版(NTS)の違いを理解するには、(1)Webサーバーが同時に複数のHTTPリクエストを処理する方法、(2)Webサーバーがphpと通信する方法、の2つを理解することが必要である。
ここではWebサーバーとしてApacheを例にとって説明する。
Apacheが同時に複数のHTTPリクエストを処理する方法
2つの方法がある。
(1) スレッドを使用する方法。即ち、1つのHTTPリクエストに1つのスレッドを割り当てる方法。worker MPMと呼ばれる。
(2) プロセスを使用する方法。即ち、1つのHTTPリクエストに1つのプロセスを割り当てる方法。prefork MPMと呼ばれる。
Windows版のApache 2.系は(1)である。つまりマルチスレッド方式である。
ApacheがPHPと通信する方法
これも2つの方法がある。
(1) phpをApache内部にモジュールとしてロードして使用する方法
(2) phpをApacheの外部アプリケーションとして(=CGIとして)使用する方法
それぞれネットの世界では様々な別名で言及されるので以下それを整理する。
(1) phpをApache内部にモジュールとしてロードして使用する方法
この場合のphpは「モジュール版」、「埋め込みインタープリター版(embedded interpreter)」とも呼ばれる。最も一般的な実装は「mod_php」である。
(2) phpをApache外部アプリとして(=CGIとして)使用する方法
この場合のphpは「CGI版」と呼ばれる。
CGIとはwebサーバーが外部アプリと通信するプロトコルのことであり、外部アプリはWebサーバーとは独立した別の1つのプロセスとして起動する。現在ではCGIを改良版したFastCGIとして実装されることが多い。代表的な実装に「mod_fcgid」、「mod_proxy_fcgi」などがある。
自分のサーバーのphpがモジュール版かCGI版かを調べる方法
phpinfo()の出力をみれば分かる。
Server APIの項目がApache 2.0 Handlerであればモジュール版であり、CGI/FastCGIであればCGI版である。
PHPの分類
ここまでにモジュール版/CGI版というPHPの分類を見てきた。これとは別にPHPにはスレッドセーフ版(TS)/ノンスレッドセーフ版(NTS)という分類もある。
この両者の関係を整理するとPHPの分類はスッキリ理解できるだろう。
結論から言えば、モジュール版=スレッド・セーフ版(TS)、CGI版=ノン・スレッド・セーフ版(NTS)と考えてよい。
スレッドセーフ版とは、マルチスレッド環境で安全に動作することを意図した実装(=worker MPM環境でモジュール版として安全に動作する)であり、ノンスレッドセーフ版とはマルチスレッド環境を想定していない実装だからである。
表にまとめると以下の通り。
Apacheの処理方式 | PHP(モジュール/CGI) | PHP(TS/NTS) |
worker MPM(スレッド) | モジュール版 | スレッドセーフ版 |
prefork MPM(プロセス) | CGI版 | ノンスレッドセーフ版 |
Windows環境におけるPHPの使い分けの実際
Windows環境では実際には以下のように使い分ければよい。
Webサーバー | php接続方式 | phpはスレッドセーフ版か? |
Apache | モジュール版(LoadModule) | Thread Safe |
Apache | CGI版(FastCGI) | Non-Thread Safe |
IIS | デフォルト | Thread Safe |
IIS | FastCGI | Non-Thread Safe |
自分のサーバーのphpがTSかNTSかを調べる方法
phpinfo()の結果を見るとわかる。Thread Safetyの項がenabledならスレッド・セーフ版、disabledならノン・スレッド・セーフ版である。
参考
http://stackoverflow.com/questions/1623914/what-is-thread-safe-or-non-thread-safe-in-php
http://stackoverflow.com/questions/7204758/php-thread-safe-and-non-thread-safe-for-windows
https://en.wikipedia.org/wiki/FastCGI
コメント