こんにちは、よろしくお願いします。
過去2週間の間、私は私を狂わせている何かに苦労してきました。WindowsボックスにAPACHE(2.2.22)とPHP(5.4.3)をインストールしていて、同時に別のプログラムを呼び出すPHPスクリプトからプログラムを呼び出そうとしています。どちらのプログラムもC/C ++で記述されており、MINGW32でコンパイルされています。Windowsのバージョンに関しては、Windows2003ServerとWindows7Professionalをテストしましたが、どちらも同じ問題が発生します。
これら2つのプログラムを紹介します。
1)mytask.exe:これはバックグラウンドで実行されるプログラムであり、定期的にそのステータスをファイルに入力します。
2)job.exe:これはPHPスクリプトから呼び出したいプログラムです。その目標は、mytask.exeを(スレッドとしてではなく)独立したプロセスとして生成することです。
コンソールウィンドウから以下のコマンドを実行すると、job.exeはすぐに戻り、mytask.exeを終了するまでバックグラウンドで実行したままにします。
> job.exe spawn mytask.exe
jobid=18874111458879FED
job.exeは、mytask.exeの管理に使用される識別子をダンプすることに注意してください。例えば:
> job.exe status 18874111458879FED
RUNNING
PHPスクリプトから最初のコマンドを実行すると、PHPスクリプトがランダムに永久にブロックされることを確認しました。Windowsのタスクマネージャーを見ると、job.exeがゾンビのような状態であることがわかります。job.exereturn 0;
はそのルーチンの通常のステートメントに効果的に到達していると断言できmain()
ます。したがって、Cランタイムでは、それは木の下にあるもののようです。さらに、単純に10秒間スリープする単純なmytask.exeを作成すると、PHPスクリプトも10秒間ブロックされます(または、今述べたランダムな動作に従って永久にブロックされます)。つまり、PHPスクリプトからjob.exeを呼び出すと、プロセスが終了するのを待たずにjob.exeがプロセスを生成するようにする方法がありません。
つまり、mytask.exeを生成するときに間違っていることがあります。そして、ここで、この余談の2番目の部分が発生します。
WINAPI関数CreateProcess()を使用して、job.exeからタスクを生成します。MSDNのドキュメントの時点でbInheritHandles = FALSE
、PHPスクリプトでI / Oデッドロックが発生する子プロセスを回避するために、を使用してCreateProcessを呼び出しています。また、PROCESS_INFORMATION構造体のCreateProcess()によって返されるプロセスハンドルを閉じます。私がしない唯一のことは、プロセスが終了するのを待つことです。一方、PHP側に関しては、 PHP関数exec()
とproc_open()
PHP関数の両方を試しましたが、job.exeを呼び出すことができませんでした。
私の最後の観察は、しかし、正しい方法であるように見えます、それでも、なぜそれらが何とか機能するのか理解できないので、それらは私を納得させません。事実、mytask.exeがfclose(stdout)
スリープする前に実行すると、PHPスクリプトはすぐに戻ります。しかし、どのように?CreateProcess()にハンドルを継承しないように指示したのに、なぜこれらの結果が得られるのですか?とにかく、job.exeによって起動されたプログラムは誰がそれらを呼び出しているかを知らない可能性があるため、このパッチに固執することはできません。したがって、これらのプログラムからstdoutを閉じることは良い解決策ではありません。UNIXでは、物事はとても単純です... 1つは単に呼び出しfork()
、標準ストリームを閉じてから呼び出しますexecve
プログラムを呼び出します。Windowsでは、CreateThread()を使用してラッパースレッドを作成し(fork()をエミュレートし)、標準ストリームを閉じた後にそのスレッドからCreateProcess()を呼び出すことも試みましたが、job.exeのストリームも閉じました。 !!
この質問はすべて1つの質問にまとめることができます。PHPから他のプロセスを作成するプログラムを実行するにはどうすればよいですか。
誰かがこの問題に光を当ててくれることを願っています...ありがとうございました!