デッドロックとは
オペレーティング システムを勉強したことがある人なら誰でも、マルチスレッドの概念を知っています。複数のスレッドでパブリック リソースにアクセスするには、リソースをロックする必要があります。アクセスが完了したらロックを解除してください。ロックが解放されないと、次のスレッドがリソースを取得するときにリソース ロックを取得できなくなり、スレッドはデッドロックになります。では、CGI はマルチスレッドのパブリック リソース アクセスによって引き起こされるデッドロックなのでしょうか?答えはいいえだ。
1. CGI はシングルスレッドプロセスであり、ps を通じて見ることができます。 (プロセスステータスS1はマルチスレッドプロセスである)。
#2. マルチスレッドであっても、PHP のシャットダウン プロセス中に glibc の time 関数が呼び出されたときにデッドロックが発生しますが、これは PHP モジュールが原因ではありません 。 glibc の時間関連関数はスレッドセーフであり、デッドロックを引き起こしません。
デッドロックの原因は何ですか?
Linux におけるデッドロックのメカニズムを分析した結果、マルチスレッドに加えて、信号処理関数もデッドロックを引き起こす可能性があることがわかりました。では、CGI のデッドロックはシグナル処理が原因なのでしょうか?その前に、一つ考えを紹介します。関数の再入可能性とシグナル安全性
関数の再入可能性とは、関数が何度入力されても、関数が正常に実行され、結果を返すことができることを意味します。 . .では、スレッドセーフ関数はリエントラントなのでしょうか?答えはいいえだ。スレッドセーフ関数は、パブリック リソースに初めてアクセスするときにグローバル ロックを取得します。関数が実行されておらず、ロックも解除されていない場合、処理は中断されます。その後、割り込み処理関数で再度アクセスするとデッドロックが発生します。それでは、割り込み処理関数ではどのような関数にアクセスできるのでしょうか?
グローバル ロックを使用しない関数に加えて、使用できるシグナル セーフ システム コールもいくつかあります。他の非シグナルセーフ関数を呼び出すと、予期しない結果 (デッドロックなど) が発生します。詳細については、マンシグナルを参照してください。デッドロックの原因を分析する前に、まずはCGIの実行プロセスを見て、デッドロックの可能性があるか分析してみましょう。PHP-CGI 実行プロセス
Glibc の time 関数は、関数のスレッド安全性を確保するためにグローバル ロックを使用しますが、信号の安全性は保証しません。以前の分析の後、私たちは当初、デッドロックの原因は PHP-CGI プロセスがシグナルを受信し、シグナル ハンドルで非シグナル セーフ関数を実行したことが原因であると疑っていました。メインプロセスが中断される前に、glibc の time 関数が実行されます。関数で取得したロックが解除される前に割り込み処理に移行します。割り込み処理中に、glibc の time 関数がアクセスされます。これによりデッドロックが発生しました。 PHP-CGI の実行プロセスは次のとおりです。解決策:
削除または簡素化qalarm によってシャットダウンに登録されたフック関数。安全でない関数呼び出しを避けてください。 上記の内容は参考用です。 推奨チュートリアル:以上がPHPファイルロックがデッドロックになった場合の対処方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。