WEB开发网
开发学院操作系统Linux/Unix linux下php多进程编程 阅读

linux下php多进程编程

 2012-12-04 20:37:04 来源:WEB开发网   
核心提示: php在很多情况用在web开发中,通常情况下一次请求对应一个php进程,linux下php多进程编程,进程执行完返回数据销毁执行过程中的中间变量代码,在一些perfork类型的的sapi中,其父进程id为1(即init进程),其6个子进程的ppid与它的pid一样,它又会等待下一个请求过来重新初始化执行环境、执行

  php在很多情况用在web开发中,通常情况下一次请求对应一个php进程,进程执行完返回数据销毁执行过程中的中间变量代码,在一些perfork类型的的sapi中,它又会等待下一个请求过来重新初始化执行环境、执行脚本,已经执行完成后的清理工作。但在如命令行下有时候一个进程满足不了需求,比如微博的异步发送,加入用php脚本处理的话,脚本需要从发送队列中取数据,然后对数据进行处理,一个进程显然太慢,解决这种问题可以用php自带的popen、exect之类的函数,也可以用php多进程编程来解决。

php的多进程管理需要pcntl和posix扩展,在官方手册中:
POSIX functions are enabled by default. You can disable POSIX-like functions with --disable-posix 。
Process Control support in PHP is not enabled by default. You have to compile the CGI or CLI version of PHP with --enable-pcntl configuration option when compiling PHP to enable Process Control support.
因为posix协议是针对unix系的,window下就不考虑了。下面用这两个扩展中的函数写一个多进程的daemon进程。

<?php
$max 	 = 6;
$current = 0;
pcntl_signal(SIGCHLD, "reduce_current");

/*
 * signal callback function 
*/
function reduce_current($signal)
{
	global $current;
	if ($signal === SIGCHLD) {
		$current--;
	}
}

// become a daemon
if (($pid = pcntl_fork()) === -1) {
	die("fork error");
} elseif ($pid) {
	exit;
} else {
	if (posix_setsid() === -1)
		die("setsid error");

	if (($pid = pcntl_fork()) === -1) 
		die("fork error");
	elseif($pid) 
		exit;

}

while(1) {
	$current++;
	if (($pid = pcntl_fork()) === -1) {
		//log and  exit

	} elseif ($pid) {
		//father process
		if ($current >= $max ) {
			//blocking
			if(pcntl_wait($status) === -1) {
				//log or exit
			}
		}

	} else {
		//child process 
		//do something repalce sleep
		sleep(3);
		exit;
	}
}

代码中规定脚本最大可以fork出6个进程,但数据达到6个后,会调用pcntl_warit使父进程挂起。当子进程执行完自己的任务(此处以sleep 3 秒代替)后退出时,父进程通过 捕获子进程退出状态,通过pcntl_signal 注册的的回调函数使其子进程数量减1,然后又可以继续fork子进程。如图中,父进程通过两次fork变成一个daemon进程,其父进程id为1(即init进程),其6个子进程的ppid与它的pid一样,都是918。

Tags:linux php 进程

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接