你好,并提前感谢您的兴趣。执行从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执行一个创建其他进程的程序?
我希望有人能够对这个问题提出一些看法......非常感谢!