php的多进程处理依赖于pcntl扩展,通过pcntl_fork创建子进程来进行并行处理。
<?php
$pid = pcntl_fork();
if($pid == -1) {
    //错误处理:创建子进程失败时返回-1.
    die(‘fork error‘);
} else if ($pid) {
    //父进程会得到子进程号,所以这里是父进程执行的逻辑
    echo "parent \n";
    //等待子进程中断,防止子进程成为僵尸进程。
    pcntl_wait($status);
} else {
    //子进程得到的$pid为0, 所以这里是子进程执行的逻辑。
    echo "child \n";
    exit;
}
<?php
$pid = pcntl_fork();
if($pid == -1) {
    die(‘fork error‘);
} else if ($pid) {
    sleep(3);
    echo "parent \n";
    pcntl_wait($status);
} else {
    echo "child \n";
    exit;
}
<?php
$pid = pcntl_fork();
if($pid == -1) {
    die(‘fork error‘);
} else if ($pid) {
    pcntl_wait ($status);
    echo "parent \n";
} else {
    sleep(3);
    echo "child \n";
    exit;
}
<?php
define(‘FORK_NUMS‘, 3);
$pids = array();
for($i = 0; $i < FORK_NUMS; ++$i) {
    $pids[$i] = pcntl_fork();
    if($pids[$i] == -1) {
        die(‘fork error‘);
    } else if ($pids[$i]) {
        pcntl_waitpid($pids[$i], $status);
        echo "pernet \n";
    } else {
        sleep(3);
        echo "child id:" . getmypid() . " \n";
        exit;
    }
}
child id:19090 pernet child id:19091 pernet child id:19092 pernet
<?php
define(‘FORK_NUMS‘, 3);
$pids = array();
for($i = 0; $i < FORK_NUMS; ++$i) {
    $pids[$i] = pcntl_fork();
    if($pids[$i] == -1) {
        die(‘fork error‘);
    } else if ($pids[$i]) {
    } else {
        sleep(3);
        echo "child id:" . getmypid() . " \n";
        exit;
    }
}
foreach($pids as $k => $v) {
    if($v) {
        pcntl_waitpid($v, $status);
        echo "parent \n";
    }
}
child id:19118 child id:19119 child id:19120 parent parent parent
<?php
define(‘FORK_NUMS‘, 3);
$pids = array();
$fp = fopen(‘./test.log‘, ‘wb‘);
$num = 1;
for($i = 0; $i < FORK_NUMS; ++$i) {
    $pids[$i] = pcntl_fork();
    if($pids[$i] == -1) {
        die(‘fork error‘);
    } else if ($pids[$i]) {
    } else {
        for($i = 0; $i < 5; ++$i) {
            flock($fp, LOCK_EX);
            fwrite($fp, getmypid() . ‘ : ‘ . date(‘Y-m-d H:i:s‘) . " : {$num} \r\n");
            flock($fp, LOCK_UN);
            echo getmypid(), ": success \r\n";
            ++$num;
        }
        exit;
    }
}
foreach($pids as $k => $v) {
    if($v) {
        pcntl_waitpid($v, $status);
    }
}
fclose($fp);
19507 : 2016-03-16 20:40:52 : 1 19507 : 2016-03-16 20:40:52 : 2 19507 : 2016-03-16 20:40:52 : 3 19507 : 2016-03-16 20:40:52 : 4 19507 : 2016-03-16 20:40:52 : 5 19509 : 2016-03-16 20:40:52 : 1 19509 : 2016-03-16 20:40:52 : 2 19509 : 2016-03-16 20:40:52 : 3 19509 : 2016-03-16 20:40:52 : 4 19509 : 2016-03-16 20:40:52 : 5 19508 : 2016-03-16 20:40:52 : 1 19508 : 2016-03-16 20:40:52 : 2 19508 : 2016-03-16 20:40:52 : 3 19508 : 2016-03-16 20:40:52 : 4 19508 : 2016-03-16 20:40:52 : 5
<?php
define(‘FORK_NUMS‘, 3);
$pids = array();
$fp = fopen(‘./test.log‘, ‘wb‘);
$num = 1;
//共享内存段的key
$shmKey = 123;
//创建共享内存段
$shmId = shmop_open($shmKey, ‘c‘, 0777, 64);
//写入数据到共享内存段
shmop_write($shmId, $num, 0);
for($i = 0; $i < FORK_NUMS; ++$i) {
    $pids[$i] = pcntl_fork();
    if($pids[$i] == -1) {
        die(‘fork error‘);
    } else if ($pids[$i]) {
        //阻塞,等待子进程退出
        //注意这里,如果是非阻塞的话,$num的计数会出现问题。
        pcntl_waitpid($pids[$i], $status);
    } else {
        //读取共享内存段中的数据
        $num = shmop_read($shmId, 0, 64);
        for($i = 0; $i < 5; ++$i) {
            fwrite($fp, getmypid() . ‘ : ‘ . date(‘Y-m-d H:i:s‘) . " : {$num} \r\n");
            echo getmypid(), ": success \r\n";
            //递增$num
            $num = intval($num) + 1;
        }
        //写入到共享内存段中
        shmop_write($shmId, $num, 0);
        exit;
    }
}
//shmop_delete不会实际删除该内存段,它将该内存段标记为删除。
shmop_delete($shmId);
shmop_close($shmId);
fclose($fp);
上述代码的运行结果如下:
19923 : 2016-03-17 00:05:18 : 1 19923 : 2016-03-17 00:05:18 : 2 19923 : 2016-03-17 00:05:18 : 3 19923 : 2016-03-17 00:05:18 : 4 19923 : 2016-03-17 00:05:18 : 5 19924 : 2016-03-17 00:05:18 : 6 19924 : 2016-03-17 00:05:18 : 7 19924 : 2016-03-17 00:05:18 : 8 19924 : 2016-03-17 00:05:18 : 9 19924 : 2016-03-17 00:05:18 : 10 19925 : 2016-03-17 00:05:18 : 11 19925 : 2016-03-17 00:05:18 : 12 19925 : 2016-03-17 00:05:18 : 13 19925 : 2016-03-17 00:05:18 : 14 19925 : 2016-03-17 00:05:18 : 15
原文:http://www.cnblogs.com/jkko123/p/6351690.html