PHP 多进程实践(一)

来源:互联网 发布:微信js接口安全域名 编辑:程序博客网 时间:2024/06/04 01:27
1. 直接方式
pcntl_fork() 创建一个进程,在父进程返回值是子进程的pid,在子进程返回值是0,-1表示创建进程失败。跟C非常相似。
测试脚本 test.php
<?php// example of multiple processesdate_default_timezone_set( 'Asia/Chongqing');echo "parent start, pid ", getmypid(), "\n" ;beep();for ($i=0; $i<3; ++$i){      $pid = pcntl_fork();       if ($pid == -1){             die ("cannot fork" );      } else if ($pid > 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<5; ++$j){                  beep();            }             exit ;      }}// ***function beep(){       echo getmypid(), "\t" , date( 'Y-m-d H:i:s', time()), "\n" ;      sleep(1);}?>



用命令行运行
#php -f test.php

输出结果
parent start, pid 1793
1793    2013-01-14 15:04:17
parent continue 
1793    2013-01-14 15:04:18
child start, pid 1794
1794    2013-01-14 15:04:18
1794    2013-01-14 15:04:19
1793    2013-01-14 15:04:19
1794    2013-01-14 15:04:20
parent continue 
1793    2013-01-14 15:04:20
child start, pid 1795
1795    2013-01-14 15:04:20
17931794                2013-01-14 15:04:212013-01-14 15:04:21

1795    2013-01-14 15:04:21
1794    2013-01-14 15:04:22
1795    2013-01-14 15:04:22
parent continue 
1793    2013-01-14 15:04:22
child start, pid 1796
1796    2013-01-14 15:04:22
1793    2013-01-14 15:04:23
1796    2013-01-14 15:04:23
1795    2013-01-14 15:04:23
1795    2013-01-14 15:04:24
1796    2013-01-14 15:04:24
1796    2013-01-14 15:04:25
1796    2013-01-14 15:04:26

从中看到,创建了3个子进程,和父进程一起并行运行。其中有一行格式跟其他有些不同,
17931794                2013-01-14 15:04:212013-01-14 15:04:21
因为两个进程同时进行写操作,造成了冲突。

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()将自己阻塞,等待子进程运行完了才接着运行。
原创粉丝点击