php 进程数-深入探索PHP多进程编程技术

2024-04-23 0 1,811 百度已收录

因为两个进程同时进行写操作,所以会产生冲突。

2. 封锁形式

采用直接方式,父进程创建子进程后,并不等待子进程结束,而是继续运行。 这里似乎没有问题。 如果php脚本运行后没有手动结束,而是常驻内存,就会导致子进程无法回收的问题。 即僵尸进程。 可以通过pcntl_wai()方法等待进程结束,然后回收已经结束的进程。

将测试脚本更改为:

$pid = pcntl_fork();
if ($pid == -1){
  ...
} else if ($pid > 0){
   echo "parent continue n";
   pcntl_wait($status);
   for ($k=0; $k<2; ++$k){
     beep();
  }
} else if ($pid == 0){
   ...
}

从命令行运行

#php -f test.php

输出结果

parent start, pid 1807
1807  2013-01-14 15:20:05
parent continue
child start, pid 1808
1808  2013-01-14 15:20:06
1808  2013-01-14 15:20:07
1808  2013-01-14 15:20:08
1808  2013-01-14 15:20:09
1808  2013-01-14 15:20:10
1807  2013-01-14 15:20:11
1807  2013-01-14 15:20:12
parent continue
child start, pid 1809
1809  2013-01-14 15:20:13
1809  2013-01-14 15:20:14
1809  2013-01-14 15:20:15
1809  2013-01-14 15:20:16
1809  2013-01-14 15:20:17
1807  2013-01-14 15:20:18
1807  2013-01-14 15:20:19
child start, pid 1810
1810  2013-01-14 15:20:20
parent continue
1810  2013-01-14 15:20:21
1810  2013-01-14 15:20:22
1810  2013-01-14 15:20:23
1810  2013-01-14 15:20:24
1807  2013-01-14 15:20:25
1807  2013-01-14 15:20:26

父进程在 pcntl_wait() 中阻塞自身php 进程数php 进程数,等待子进程完成运行后再继续。

3.非阻塞形式

阻塞形式失去了多进程的并行性。 还有一种方法可以回收已经结束的子进程并并行执行它们。 这是非阻塞形式。

修改脚本:

<?php
  // example of multiple processes
  date_default_timezone_set( 'Asia/Chongqing');
  declare (ticks = 1);
  pcntl_signal(SIGCHLD, "garbage" );
  echo "parent start, pid ", getmypid(), "n" ;
  beep();
  for ($i=0; $i 0){
         echo "parent continue n";
         for ($k=0; $k<2; ++$k){
           beep();
        }
     } else if ($pid == 0){
         echo "child start, pid ", getmypid(), "n" ;
         for ($j=0; $j 0){
         echo "t child end pid $pid , status $statusn" ;
     }
  }
  function beep(){
      echo getmypid(), "t" , date( 'Y-m-d H:i:s', time()), "n" ;
     sleep(1);
  }
?>

从命令行运行

#php -f test.php &

输出结果

parent start, pid 2066
2066  2013-01-14 16:45:34
parent continue
2066  2013-01-14 16:45:35
child start, pid 2067
2067  2013-01-14 16:45:35
20662067        2013-01-14 16:45:362013-01-14 16:45:36
2067  2013-01-14 16:45:37
parent continue
2066  2013-01-14 16:45:37
child start, pid 2068
2068  2013-01-14 16:45:37
2067  2013-01-14 16:45:38
2068  2013-01-14 16:45:38
2066  2013-01-14 16:45:38
parent continue
2066  2013-01-14 16:45:40
child start, pid 2069
2069  2067  2013-01-14 16:45:40
2013-01-14 16:45:40
2068  2013-01-14 16:45:40
2066  2013-01-14 16:45:41
2069  2013-01-14 16:45:41
2068  2013-01-14 16:45:41
signel 17 received
     child end pid 2067, status 0
2069  2013-01-14 16:45:42
2068  2013-01-14 16:45:42
2069  2013-01-14 16:45:43
signel 17 received
     child end pid 2068, status 0
2069  2013-01-14 16:45:44
signel 17 received
     child end pid 2069, status 0

多个进程再次并行运行,运行10秒左右后,使用ps -ef | grep php 检查正在运行的进程。 只有一个过程。

lqling 2066 1388 0 16:45 点/1 00:00:00 php -f t5.php

就是父进程和子进程被回收了。

子进程退出状态

pcntl_waitpid(-1, $status, WNOHANG) $status

返回子进程的结束状态

windows下多线程

Windows系统不支持pcntl函数。 幸运的是,有curl_multi_exec()这​​个工具,它使用内部多线程访问多个链接,每个链接都可以作为一个任务。

编写脚本test1.php

 $task){
     $ch[$i] = curl_init();
     curl_setopt($ch[$i], CURLOPT_URL, $task);
     curl_setopt($ch[$i], CURLOPT_RETURNTRANSFER, 1);
     curl_multi_add_handle($mh, $ch[$i]);
  }
  do {$mrc = curl_multi_exec($mh,$active); } while ($mrc == CURLM_CALL_MULTI_PERFORM);
  while ($active && $mrc == CURLM_OK) {
     if (curl_multi_select($mh) != -1) {
      do {$mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM);
     }
  }
  // completed, checkout result
  foreach ($tasks as $j => $task){
     if (curl_error($ch[$j])){
       echo "task ${j} [$task ] error " , curl_error($ch[$j]), "rn" ;
     } else {
       echo "task ${j} [$task ] get: rn" , curl_multi_getcontent($ch[$j]), "rn" ;
     }
  }
?>

编写脚本test2.php

<?php
  date_default_timezone_set( 'Asia/Chongqing');
  echo "child start, pid ", getmypid(), "rn" ;
  for ($i=0; $i

从命令行运行

#php -f test1.php &

输出结果

task 0 [http://localhost/feedbowl/t2.php?job=task1] get:
child start, pid 5804
5804  2013-01-15 20:22:35
5804  2013-01-15 20:22:36
5804  2013-01-15 20:22:37
5804  2013-01-15 20:22:38
5804  2013-01-15 20:22:39
task 1 [http://localhost/feedbowl/t2.php?job=task2] get:
child start, pid 5804
5804  2013-01-15 20:22:35
5804  2013-01-15 20:22:36
5804  2013-01-15 20:22:37
5804  2013-01-15 20:22:38
5804  2013-01-15 20:22:39
task 2 [http://localhost/feedbowl/t2.php?job=task3] get:
child start, pid 5804
5804  2013-01-15 20:22:35
5804  2013-01-15 20:22:36
5804  2013-01-15 20:22:37
5804  2013-01-15 20:22:38
5804  2013-01-15 20:22:39

从复制的时间我们可以看到,多个任务几乎是同时运行的。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 php php 进程数-深入探索PHP多进程编程技术 https://www.wkzy.net/game/200693.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务