注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

phperwuhan的博客

记载一个phper的历程!phperwuhan.blog.163.com

 
 
 

日志

 
 

PCNTL函数族--PHP多进程编程  

2010-07-19 12:14:42|  分类: php |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

来源:http://blog.csdn.net/fafa211/archive/2010/05/02/5550558.aspx

php有一组进程控制函数,使得php能在*nix系统中实现跟c一样的创建子进程、使用exec函数执行程序、处理信号等功能。

引用
Process Control support in PHP implements the Unix style of process creation, program execution, signal handling and process termination. Process Control should not be enabled within a web server environment and unexpected results may happen if any Process Control functions are used within a web server environment.


谨以此句献给超工,在web server环境中不要使用这组函数,因为会导致不可预料的结果。另,windows作为非类unix系统,没有这些函数。

PCNTL使用ticks来作为信号处理机制(signal handle callback mechanism),可以最小程度地降低处理异步事件时的负载。何谓ticks?Tick 是一个在代码段中解释器每执行 N 条低级语句就会发生的事件,这个代码段需要通过declare来指定。

PCNTL的函数都有这么些:
信号处理
int pcntl_alarm ( int $seconds )
设置一个$seconds秒后发送SIGALRM信号的计数器

bool pcntl_signal ( int $signo , callback $handler [, bool $restart_syscalls ] )
为$signo设置一个处理该信号的回调函数

下面是一个隔5秒发送一个SIGALRM信号,并由signal_handler函数获取,然后打印一个“Caught SIGALRM”的例子:

  1. <?php   
  2.     declare(ticks = 1);   
  3.   
  4.     function signal_handler($signal) {   
  5.         print "Caught SIGALRM\n";   
  6.         pcntl_alarm(5);   
  7.     }   
  8.   
  9.     pcntl_signal(SIGALRM, "signal_handler", true);   
  10.     pcntl_alarm(5);   
  11.   
  12.     for(;;) {   
  13.     }   
  14.   
  15. ?>  

  1. <?php   
  2.     declare(ticks = 1);   
  3.   
  4.     function signal_handler($signal) {   
  5.         print "Caught SIGALRM\n";   
  6.         pcntl_alarm(5);   
  7.     }   
  8.   
  9.     pcntl_signal(SIGALRM, "signal_handler", true);   
  10.     pcntl_alarm(5);   
  11.   
  12.     for(;;) {   
  13.     }   
  14.   
  15. ?>  

<?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(;;) {     } ?>

执行程序
void pcntl_exec ( string $path [, array $args [, array $envs ]] )
在当前的进程空间中执行指定程序,类似于c中的exec族函数。所谓当前空间,即载入指定程序的代码覆盖掉当前进程的空间,执行完该程序进程即结束。

  1. <?php   
  2. $dir = '/home/shankka/';   
  3. $cmd = 'ls';   
  4. $option = '-l';   
  5. $pathtobin = '/bin/ls';   
  6.   
  7. $arg = array($cmd$option$dir);   
  8.   
  9. pcntl_exec($pathtobin$arg);   
  10. echo '123';    //不会执行到该行   
  11. ?>  

  1. <?php   
  2. $dir = '/home/shankka/';   
  3. $cmd = 'ls';   
  4. $option = '-l';   
  5. $pathtobin = '/bin/ls';   
  6.   
  7. $arg = array($cmd$option$dir);   
  8.   
  9. pcntl_exec($pathtobin$arg);   
  10. echo '123';    //不会执行到该行   
  11. ?>  

<?php $dir = '/home/shankka/'; $cmd = 'ls'; $option = '-l'; $pathtobin = '/bin/ls'; $arg = array($cmd, $option, $dir); pcntl_exec($pathtobin, $arg); echo '123';    //不会执行到该行 ?>

创建进程
int pcntl_fork ( void )
为当前进程创建一个子进程

int pcntl_wait ( int &$status [, int $options ] )
阻塞当前进程,只到当前进程的一个子进程退出或者收到一个结束当前进程的信号。

int 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这些函数。

来个例子:

  1. <?php   
  2. $pid = pcntl_fork();   
  3. if($pid)   
  4. {   
  5.         pcntl_wait($status);   
  6.         $id = getmypid();   
  7.         echo "parent process,pid {$id}, child pid {$pid}\n";   
  8. }   
  9. else  
  10. {   
  11.         $id = getmypid();   
  12.         echo "child process,pid {$id}\n";   
  13.         sleep(2);   
  14. }   
  15. ?>  

  1. <?php   
  2. $pid = pcntl_fork();   
  3. if($pid)   
  4. {   
  5.         pcntl_wait($status);   
  6.         $id = getmypid();   
  7.         echo "parent process,pid {$id}, child pid {$pid}\n";   
  8. }   
  9. else  
  10. {   
  11.         $id = getmypid();   
  12.         echo "child process,pid {$id}\n";   
  13.         sleep(2);   
  14. }   
  15. ?>  

<?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秒才结束,而父进程阻塞着直到子进程退出之后才继续运行。

进程优先级:
int pcntl_getpriority ([ int $pid [, int $process_identifier ]] )
取得进程的优先级,即nice值,默认为0,在我的测试环境的linux中(CentOS release 5.2 (Final)
),优先级为-20到19,-20为优先级最高,19为最低。(手册中为-20到20)

bool pcntl_setpriority ( int $priority [, int $pid [, int $process_identifier ]] )
设置进程的优先级

  评论这张
 
阅读(1064)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017