PHP 4和5,Ctrl-C,system()和子进程

时间:2021-10-20 22:43:03

I have a PHP script that uses the system() call to execute other (potentially long-running) programs (for interest: NCBI BLAST, phrap, primer3 and other programs for doing DNA sequence analysis and assembly).

我有一个PHP脚本,它使用system()调用来执行其他(可能是长期运行的)程序(感兴趣的是:NCBI BLAST,phrap,primer3和其他用于进行DNA序列分析和组装的程序)。

I'm running under Windows XP, using the CLI version of PHP from a command prompt, or as a service. (In either case I communicate with it via a queue of tasks in a database table).

我在Windows XP下运行,在命令提示符下使用CLI版本的PHP,或作为服务运行。 (在任何一种情况下,我都通过数据库表中的任务队列与之通信)。

Under PHP4: when I hit Ctrl+C the script is stopped and any child process running at the time is also stopped. Under PHP5: when I hit Ctrl+C the script stops, but the child is left running.

在PHP4下:当我按下Ctrl + C时,脚本停止,此时运行的所有子进程也会停止。在PHP5下:当我按下Ctrl + C时脚本停止,但是孩子继续运行。

Similarly, when running the script as a service, stopping the service when running it with PHP4 stops the child, with PHP5 the child continues to run.

类似地,当将脚本作为服务运行时,在使用PHP4运行它时停止服务会停止该子服务,使用PHP5,子服务器将继续运行。

I have tried writing a minimal test application, and found the same behaviour. The test PHP script just uses system() to execute a C program (that just sleeps for 30 seconds) and then waits for a key to be pressed.

我试过写一个最小的测试应用程序,并发现了相同的行为。测试PHP脚本只使用system()来执行C程序(只能休眠30秒),然后等待按下一个键。

I had a look at the source for PHP 4.4.9 and 5.2.6 but could see no differences in the system() code that looked like they would cause this. I also had a quick look at the startup code for the CLI application and didn't see any differences in signal handling.

我查看了PHP 4.4.9和5.2.6的源代码,但是看不出它们会导致这种情况的system()代码没有差异。我还快速查看了CLI应用程序的启动代码,但没有看到信号处理方面的任何差异。

Any hints on what might have caused this, or a workaround, would be appreciated.

任何可能导致此问题或解决方法的提示都将受到赞赏。

Thanks.

2 个解决方案

#1


1  

This issue occurs in at least PHP 5.1.2.

至少在PHP 5.1.2中会出现此问题。

When a SIGINT is sent via CTRL+C or CTRL+BREAK, the handler is called. If this handler sends a SIGTERM to other children, the signals are not received.

通过CTRL + C或CTRL + BREAK发送SIGINT时,将调用该处理程序。如果此处理程序将SIGTERM发送给其他子项,则不会收到信号。

SIGINT can be sent via posix_kill() and it work exactly as expected-- This only applies when initiated via a hard break.

SIGINT可以通过posix_kill()发送,并且它完全按预期工作 - 这仅适用于通过硬中断启动时。

From: http://php.oregonstate.edu/manual/en/function.pcntl-signal.php

The document has sample code for trapping CTRL+C and sending posix_kill to children. It has lots of other code and info on child precesses and signals.

该文档包含用于捕获CTRL + C并将posix_kill发送给子项的示例代码。它有很多关于儿童进出和信号的其他代码和信息。

#2


1  

Instead of using system(), have a look at proc_open(), proc_close() and proc_terminate().

不要使用system(),而是查看proc_open(),proc_close()和proc_terminate()。

#1


1  

This issue occurs in at least PHP 5.1.2.

至少在PHP 5.1.2中会出现此问题。

When a SIGINT is sent via CTRL+C or CTRL+BREAK, the handler is called. If this handler sends a SIGTERM to other children, the signals are not received.

通过CTRL + C或CTRL + BREAK发送SIGINT时,将调用该处理程序。如果此处理程序将SIGTERM发送给其他子项,则不会收到信号。

SIGINT can be sent via posix_kill() and it work exactly as expected-- This only applies when initiated via a hard break.

SIGINT可以通过posix_kill()发送,并且它完全按预期工作 - 这仅适用于通过硬中断启动时。

From: http://php.oregonstate.edu/manual/en/function.pcntl-signal.php

The document has sample code for trapping CTRL+C and sending posix_kill to children. It has lots of other code and info on child precesses and signals.

该文档包含用于捕获CTRL + C并将posix_kill发送给子项的示例代码。它有很多关于儿童进出和信号的其他代码和信息。

#2


1  

Instead of using system(), have a look at proc_open(), proc_close() and proc_terminate().

不要使用system(),而是查看proc_open(),proc_close()和proc_terminate()。