PHP多历程编程

时间:2014-02-15所属栏目: PHP/PHP框架 来源: 未知 热度:

行使PHP真正的多历程运行模式,合用于数据收罗、邮件群发、数据源更新、tcp处事器等环节。

PHP有一组历程节制函数(编译时必要 –enable-pcntl与posix扩展),使得php能在*nix体系中实现跟c一样的建设子历程、行使exec函数执行措施、处理赏罚信号等成果。 PCNTL行使ticks来作为信号处理赏罚机制(signal handle callback mechanism),可以最小水平地低落处理赏罚异步变乱时的负载。何谓ticks?Tick 是一个在代码段中表明器每执行 N 条初级语句就会产生的变乱,这个代码段必要通过declare来指定。

常用的PCNTL函数
1. pcntl_alarm ( int $seconds )
配置一个$seconds秒后发送SIGALRM信号的计数器

2. pcntl_signal ( int $signo , callback $handler [, bool $restart_syscalls ] )
为$signo配置一个处理赏罚该信号的回调函数。下面是一个隔5秒发送一个SIGALRM信号,并由signal_handler函数获取,然后打印一个“Caught SIGALRM”的例子:

<?php  
declare(ticks = 1);  

function signal_handler($signal) {  
	print "Caught SIGALRM\n";  
    pcntl_alarm(5);  
}  

pcntl_signal(SIGALRM, "signal_handler", true);  
pcntl_alarm(5);  

for(;;) {  
}  

?>

3. pcntl_exec ( string $path [, array $args [, array $envs ]] )
在当前的历程空间中执行指定措施,相同于c中的exec族函数。所谓当前空间,即载入指定措施的代码包围掉当前历程的空间,执行完该措施历程即竣事。

<?php  
$dir = '/home/shankka/';  
$cmd = 'ls';  
$option = '-l';  
$pathtobin = '/bin/ls';  

$arg = array($cmd, $option, $dir);  

pcntl_exec($pathtobin, $arg);  
echo '123';    //不会执行到该行  
?>

4. pcntl_fork ( void )
为当前历程建设一个子历程,而且先运行父历程,返回的是子历程的PID,必定大于零。在父历程的代码中可以用 pcntl_wait(&$status)停息父历程知道他的子历程有返回值。留意:父历程的阻塞同时会阻塞子历程。可是父历程的竣事不影响子历程的运行。
父历程运行完了会接着运行子历程,这时子历程会从执行pcntl_fork()的那条语句开始执行(包罗此函数),可是此时它返回的是零(代表这是一个子历程)。在子历程的代码块中最好有exit语句,即执行完子历程后当即就竣事。不然它会又重头开始执行这个剧本的某些部门。

留意两点:
1. 子历程最好有一个exit;语句,防备不须要的堕落;
2. pcntl_fork间最好不要有其余语句,譬喻:

<?php
$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 
}
?>

5. pcntl_wait ( int &$status [, int $options ] )
阻塞当前历程,只到当前历程的一个子历程退出可能收到一个竣事当前历程的信号。行使$status返回子历程的状态码,并可以指定第二个参数来声名是否以阻塞状态挪用:
1. 阻塞方法挪用的,函数返回值为子历程的pid,假如没有子历程返回值为-1;
2. 非阻塞方法挪用,函数还可以在有子历程在运行但没有竣事的子历程时返回0。

6. pcntl_waitpid ( int $pid , int &$status [, int $options ] )
成果同pcntl_wait,区别为waitpid为守候指定pid的子历程。当pid为-1时pcntl_waitpid与pcntl_wait 一样。在pcntl_wait和pcntl_waitpid两个函数中的$status中存了子历程的状态信息,这个参数可以用于 pcntl_wifexited、pcntl_wifstopped、pcntl_wifsignaled、pcntl_wexitstatus、 pcntl_wtermsig、pcntl_wstopsig、pcntl_waitpid这些函数。
譬喻:

  
<?php  
$pid = pcntl_fork();  
if($pid) {  
    pcntl_wait($status);  
    $id = getmypid();  
    echo "parent process,pid {$id}, child pid {$pid}\n";  
}else{  
    $id = getmypid();  
    echo "child process,pid {$id}\n";  
    sleep(2);  
}  
?>

子历程在输出child process等字样之后sleep了2秒才竣事,而父历程阻塞着直到子历程退出之后才继承运行。

标签:
评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)