昨天组内同学在使用php父子进程模式的时候遇到了一个比较诡异的问题
简单说来就是:因为fork,父子进程共享了一个redis连接、然后父子进程在发送了各自的redis请求分别获取到了对方的响应体。
复现示例代码:
testFork.php
1 <?php
2 require_once("./PowerSpawn.php");
3
4 $ps = new Forkutil_PowerSpawn();
5 $ps->maxChildren = 10 ;
6 $ps->timeLimit = 86400;
7
8 $redisObj = new Redis();
9 $redisObj->connect('127.0.0.1','6379');
10
11 // 主进程 -- 查询任务列表并新建子进程
12 while ($ps->runParentCode()) {
13 echo "parent:".$redisObj->get("parent")."\n" ;
14 // 产生一个子进程
15 if ($ps->spawnReady()) {
16 $ps->spawnChild();
17 } else {
18 // 队列已满,等待
19 $ps->Tick();
20 }
21 }
22
23 // 子进程 -- 处理具体的任务
24 if ($ps->runChildCode()) {
25 echo "chlidren:".$redisObj->get("children")."\n" ;
26 }
PowerSpawn.php 主要用户进程fork管理工作
<?php
/*
* PowerSpawn
*
* Object wrapper for handling process forking within PHP
* Depends on PCNTL package
* Depends on POSIX package
*
* Author: Don Bauer
* E-Mail: [email protected]
*
* Date: 2011-11-04
*/
declare(ticks = 1);
class Forkutil_PowerSpawn
{
private $myChildren;
private $parentPID;
private $shutdownCallback = null;
private $killCallback = null;
public $maxChildren = 10; // Max number of children allowed to Spawn
public $timeLimit = 0; // Time limit in seconds (0 to disable)
public $sleepCount = 100; // Number of uSeconds to sleep on Tick()
public $childData;