当前位置:  编程技术>php
本页文章导读:
    ▪有关php多进程的用法举例      在php中实现多进程,一般有两种方法,一种是使用PHP自带的pcntl_*函数(仅限linux),另一种就是使用popen/proc_open,然后在php内部控制进程数量。 使用pcntl_*函数 PHP提供了一系列的pcntl_*函数,顾.........
    ▪linux查看PHP进程是否在执行的实例代码      代码如下:   代码示例: <?php //检查sh.php是否在执行 //modify by www. function check_php(){ $fname=$this->cachedir."/stat"; $str="ps -ax|grep php > $fname"; exec($str); //执行系统命令 $str="grep sh $fname|wc -l";.........
    ▪php中启用多进程的实例详解(ubuntu系统)      1,首先,在ubuntu系统中编译pcntl.so,如果找不到pcntl的包,可以创建一个文件夹,下载整个PHP包,在其中找到pcntl包。 然后运行命令:   代码示例: mkdir php cd php apt-get source php5 cd php5-(WHATEV.........

[1]有关php多进程的用法举例
    来源: 互联网  发布时间: 2013-12-24

在php中实现多进程,一般有两种方法,一种是使用PHP自带的pcntl_*函数(仅限linux),另一种就是使用popen/proc_open,然后在php内部控制进程数量。
使用pcntl_*函数

PHP提供了一系列的pcntl_*函数,顾名思义就是process control functions,专门用来管理进程的。最常用的就是pcntl_fork和pcntl_wait。

pcntl_fork的作用就是从当前的进程再派生出一个子进程。pcntl_wait的作用是挂起当前进程,直到一个子进程中止。
例子:
 

代码示例:
<?php
//配合pcntl_signal使用
declare(ticks=1);
//最大的子进程数量
$max = 5;
//当前的子进程数量
$child = 0;
 
//当子进程退出时,会触发该函数
function sig_handler($sig) {
 global $child;
 switch($sig) {
  case SIGCHLD:
   echo 'SIGCHLD received'."\n";
   $child--;
 }
}
 
//注册子进程退出时调用的函数
pcntl_signal(SIGCHLD, "sig_handler");
 
while(true) {
 $child++;
 /**
  * 这个函数会返回两个值,一个为0,表示子进程;一个为正整数表示子进程的id
  * 所以if和else里的两段代码都会执行
  * if里的代码是父进程执行的
  * else里的代码是子进程执行的
  */
 $pid = pcntl_fork();
 if ($pid) {
  //这里是父进程执行的代码
  //如果子进程数超过了最大值,则挂起父进程
  //也就是说while语句不会继续执行
  if ($child >= $max) {
   pcntl_wait($status);
  }
 }
 else {
  //这里是子进程执行的代码
  //如果要执行其他命令的话,使用pcntl_exec
  echo "starting new child | now we have $child child process\n";
  sleep(rand(3, 5));
  exit;
 }
}
?>

上面这段代码就是保证有5个子进程一直在干活,如果$child数量大于$max,就等子进程结束后再继续运行。子进程结束后会调用 sig_handler函数,sig_handler会将$child
数量减1,那边while继续执行。

使用popen/proc_open

popen会创建一个管道来连接该进程,然后使用fread/fgets/stream_get_contents来读取该进程返回的结果。跟 exec或system之类的函数不同的是,exec会等待命令执行完
成,再运行下面的代码,但popen不会。proc_open又更加强大一些,支持 stdin和stdout,路径设置等等。

因为这些函数只负责创建,没有相应的管理方法,所以只能在PHP文件内部自己来实现。
演示示例:(PHP多进程并发控制的测试实例)
 

代码示例:
<?php
function run($input)
{
    global $p_number;
    if ($p_number <= 0)
    {
        $p_number = worker_processes($p_number);
    }
    $p_number = $p_number - 1;
    $out = popen("/bin/sh /opt/zhangyan.sh \"{$input}\" &", "r");
    pclose($out);
}
 
function worker_processes($p_number)
{
    $limit = 500;//允许推到后台的最大进程数
    while ($p_number <= 0)
    {
        $cmd = popen("ps -ef | grep \"/opt/zhangyan.sh\" | grep -v grep | wc -l", "r");
        $line = fread($cmd, 512);
        pclose($cmd);
        $p_number = $limit - $line;
        if ($p_number <= 0)
        {
            sleep(1);//暂停1秒钟
        }
    }
    return $p_number;
}
 
$input = "http://www."; //模拟从队列文件中读取到的数据
for ($i = 1; $i <= 1000; $i++)
{
    run($input);
    echo "Idle process number: " . $p_number . "\n";
}
?>

代码说明:

1. 设置/opt/zhangyan.php最多允许生成500个子进程;

2. 当/opt/zhangyan.php读取到一条数据后,将允许生成的子进程数减1(空闲进程数$p_number=500-1=499),然后将数据交给/opt/zhangyan.sh去后台处理,不等待
/opt/zhangyan.sh处理结束,继续读取下一条数据;

3. 当允许生成的子进程数减至0时(空闲进程数$p_number=0),/opt/zhangyan.php会等待1秒钟,然后检查后台还有多少个/opt /zhangyan.sh子进程尚未处理结束;

4. 如果1秒钟之后/opt/zhangyan.php发现后台的/opt /zhangyan.sh子进程数还是500(空闲进程数$p_number=0),会继续等待1秒钟,如此反复;

5. 如果/opt /zhangyan.php发现后台尚未处理结束的/opt/zhangyan.sh子进程数减少到300个了(空闲进程数$p_number=500-300=200),那么/opt/zhangyan.php会再往后台
推送200个/opt/zhangyan.sh子进程;

建议使用pcntl_*系函数更方便一些,逻辑更清楚。


    
[2]linux查看PHP进程是否在执行的实例代码
    来源: 互联网  发布时间: 2013-12-24

代码如下:
 

代码示例:
<?php
//检查sh.php是否在执行
//modify by www.
function check_php(){
$fname=$this->cachedir."/stat";
$str="ps -ax|grep php > $fname";
exec($str); //执行系统命令
$str="grep sh $fname|wc -l"; //查看sh.php是否在执行
$tmp=exec($str);
if ($tmp<1){//不在运行
return true;
}
if ($tmp>1){ //在运行
$time=filemtime($this->cachedir."/myaccess_log"); //得到这个文件最后被更新过的时间
if ((time()-$time)>150) //如果现在时间离上次执行的时间超过了150秒,则认为进程僵死,超过时间没有运行。
{
echo "进程sh.php在.$this->mytime.被发现已经僵死\n";
//写入日志文件C
$check_msg="进程sh.php在 $this->dateandtime 被发现已经僵死\n";
$c_fname=$this->datadir."/c";
$fd=fopen($c_fname,"a");
fwrite($fd,$check_msg);
fclose($fd);
$this->kill_php();
return true;
}
return false;
}
}
//如果程序僵死杀死进程
function kill_php(){
exec("killall -9 sh.php");
//exec("killall -9 php");
echo "进程sh.php在.$this->mytime.被杀死\n";
$check_msg="进程sh.php在 $this->dateandtime 被杀死\n";
$c_fname=$this->datadir."/c";
$fd=fopen($c_fname,"a");
fwrite($fd,$check_msg);
fclose($fd);
}
?>

    
[3]php中启用多进程的实例详解(ubuntu系统)
    来源: 互联网  发布时间: 2013-12-24

1,首先,在ubuntu系统中编译pcntl.so,如果找不到pcntl的包,可以创建一个文件夹,下载整个PHP包,在其中找到pcntl包。
然后运行命令:
 

代码示例:
mkdir php
cd php
apt-get source php5
cd php5-(WHATEVER_RELEASE)/ext/pcntl
phpize
./configure
 

将编译好的pcntl.so复制到系统php的拓展文件夹下,具体位置看phpinfo中的说明。
例如:
 

代码示例:
cp modules/pcntl.so /usr/lib/php5/WHEVER_YOUR_SO_FILES_ARE/
echo "extension=pcntl.so" > /etc/php5/conf.d/pcntl.ini

查看phpinfo信息,看是否已加载pcntl。

2,开始pcntl_fork
测试代码如下:
 

代码示例:

<?php
/**
* php 多进程演示
* edit www.
*/
    //while(1)//循环采用3个进程
    $bWaitFlag = FALSE; // 是否等待进程结束
    //$bWaitFlag = TRUE; // 是否等待进程结束
    $intNum = 3; // 进程总数
    $pids = array(); // 进程PID数组

    for($i = 0; $i <$intNum; $i++) {

    $pids[$i] = pcntl_fork();// 产生子进程,而且从当前行之下开试运行代码,而且不继承父进程的数据信息
    if($pids[$i] == -1) {
    echo "couldn't fork". "\n";
    }elseif(!$pids[$i]) {
    sleep(1);
    echo "\n"."第".$i."个进程 -> " . time(). "\n";
    //$url=" http://xxx/comments.php?p=".$i;//抓取页面的例子
    //$content = file_get_contents($url);
    //file_put_contents('message.txt',$content);
    //echo "\n"."第".$i."个进程 -> " ."抓取页面".$i."-> " . time()."\n";
    exit(0);//子进程要exit否则会进行递归多进程,父进程不要exit否则终止多进程
        }
        if ($bWaitFlag) {
            pcntl_waitpid($pids[$i], $status, WUNTRACED);echo "wait $i -> " . time() . "\n";
        }
    }
?>

保存为fork.php,然后,在命令行运行:
# php fork.php。
 


    
最新技术文章:
▪PHP函数microtime()时间戳的定义与用法
▪PHP单一入口之apache配置内容
▪PHP数组排序方法总结(收藏)
▪php数组排序方法大全(脚本学堂整理奉献)
▪php数组排序的几个函数(附实例)
▪php二维数组排序(实例)
▪php根据键值对二维数组排序的小例子
▪php验证码(附截图)
▪php数组长度的获取方法(三个实例)
▪php获取数组长度的方法举例
▪判断php数组维度(php数组长度)的方法
▪php获取图片的exif信息的示例代码
▪PHP 数组key长度对性能的影响实例分析
▪php函数指定默认值的方法示例
▪php提交表单到当前页面、提交表单后页面重定...
▪php四舍五入的三种实现方法
▪php获得数组长度(元素个数)的方法
▪php日期函数的简单示例代码
▪php数学函数的简单示例代码
▪php字符串函数的简单示例代码
▪php文件下载代码(多浏览器兼容、支持中文文...
▪php实现文件下载、支持中文文件名的示例代码...
▪php文件下载(防止中文文件名乱码)的示例代码
▪解决PHP文件下载时中文文件名乱码的问题
▪php数组去重(一维、二维数组去重)的简单示例
▪php小数点后取两位的三种实现方法
▪php Redis 队列服务的简单示例
▪PHP导出excel时数字变为科学计数的解决方法
▪PHP数组根据值获取Key的简单示例
▪php数组去重的函数代码示例
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3