你好,並提前感謝您的興趣。執行從PHP程序掛起APACHE
在過去的兩個星期裏,我一直在苦苦掙扎,我在Windows上安裝了APACHE(2.2.22)和PHP(5.4.3),我試圖從一個PHP腳本調用另一個程序同時調用的程序。這兩個程序都是用C/C++編寫的,並用MINGW32編譯。關於Windows版本,我測試了Windows 2003 Server和Windows 7 Professional,兩者都給我提出了相同的問題。
我來介紹一下這兩種方案:
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.exe有效地達到了main()
例程中通常的return 0;
聲明,所以它似乎是C運行時中的一些東西。另外,如果我編寫簡單的睡眠10秒的簡單mytask.exe,那麼PHP腳本也會阻塞10秒(或者在我剛剛提到的隨機行爲之後永遠阻塞)。換句話說,當我從PHP腳本調用job.exe時,我無法讓job.exe產生一個進程而無需等待它結束。
因此:產生mytask.exe時出現了一些問題,現在,這裏是第二部分。
我使用WINAPI函數CreateProcess()從job.exe產生任務。從MSDN文檔中,我使用bInheritHandles = FALSE
調用CreateProcess,以避免子進程使用PHP腳本產生I/O死鎖。我還關閉了PROCESS_INFORMATION結構中由CreateProcess()返回的進程句柄。我唯一不做的就是等待這個過程結束。另一方面,關於PHP方面,我已經嘗試了exec()
和proc_open()
PHP函數來調用job.exe沒有成功。
雖然我最近的觀察結果似乎是正確的,但他們沒有說服我,因爲我不明白他們爲什麼要以某種方式工作。事實是,如果mytask.exe在睡眠之前做了fclose(stdout)
,那麼PHP腳本會立即返回。但是,如何?我告訴CreateProcess()不要繼承句柄,爲什麼我會得到這些結果?無論如何,我不能堅持這個補丁,因爲job.exe啓動的程序可能不知道誰在調用它們,所以從這些程序中關閉stdout不是一個好的解決方案。在UNIX中,事情非常簡單...只需調用fork()
,關閉標準流,然後調用execve
來調用程序。在Windows中,我也嘗試使用CreateThread()創建一個包裝器線程(以模擬fork()),然後在關閉標準流之後從該線程調用CreateProcess()......但是這封閉了作業流。exe也是!
所有這個問題都可以合成一個:我怎樣才能從PHP執行一個創建其他進程的程序?
我希望有人能夠對這個問題提出一些看法......非常感謝!