2008年11月24日星期一

PHP 命令行 fork 多进程处理

很多人认为 PHP 没有多线程和多进程处理能力,其实 PHP 有多种运行模式。作为在作 web 应用的时候通常运行于 cgi 或者 web api 模块模式,web 服务器本身多进程或线程方式运行。而 PHP 在 cli 命令行模式下则有能力使用 fork 产生子进程(Windows 环境不可用)。本文将论述这种情况。

PHP 的进程控制支持实现了 Unix 类型的进程创建、程序执行、信号处理和进程终止。在 web 服务环境中不应该启用进程控制,如果在 web 服务环境中使用进程控制功能可能导致不可预料的结果。

int pcntl_fork(void)
fork 的意思是叉子,分岔路口。同样程序在这里分叉 ^_^。fork() 函数执行后,系统会将当前进程复制一份,子进程和父进程的差别只有 PID(进程号) 和 PPID(父进程号)不同。也就是说,这一点开始除了PID和PPID,子进程和父进程有同样的数据,也正在同样的控制流程中。所以注意一点,如果父进程在循环中fork(), 那么子进程也在循环中。
分叉点在这儿,fork()返回值:
  • 父进程从 fork() 得到的返回值是子进程的PID, 
  • 子进程从 fork() 得到的返回值是 0,
  • 如果父进程得到返回值是 -1 表示有错误发生,比如系统资源耗尽导致无法创建子进程。
因为创建的是进程,而每个进程的空间是相互独立的,所以在fork()这一刻子进程和父进程拥有相同的数据和状态,随后各自独立运行,改变的数据和状态不会相互影响。
$pid = pcntl_fork();
if ($pid == -1) {
     die('could not fork');
} else if ($pid) {
     // we are the parent
     pcntl_wait($status); //Protect against Zombie children
} else {
     // we are the child
}


[未完待续……]