PHP多线程pcntl

一 安装pcntl扩展
和其他的扩展一样步骤,如下:
1,到扩展目录下
# cd /usr/local/src/php-5.5.18/ext/pcntl
2,执行phpize

# /usr/local/php/bin/phpize
3,添加配置
# ./configure –with-php-config=/usr/local/php/bin/php-config
# make && make install
4,php.ini添加配置
[stomp]
extension = stomp.so
二 使用pcntl
FORK编程的大概原理是,每次调用fork函数,操作系统就会产生一个子进程,儿子进程所有的堆栈信息都是原封不动复制父进程的,而在fork之后,父进程与子进程实际上是相互独立的,父子进程不会相互影响。也就是说,fork调用位置之前的所有变量,父进程和子进程是一样的,但fork之后则取决于各自的动作,且数据也是独立的;因为数据已经完整的复制给了子进程。而唯一能够区分父子进程的方法就是判断fork的返回值。如果为0,表示是子进程,如果为正数,表示为父进程,且该正数为子进程的PID(进程号),而如果是-1,表示子进程创建失败
三 实例
以下实例在cli模式下运行,均摘自php.net

        for ($i = 1; $i <= 5; ++$i) {
            $pid = pcntl_fork();
        
            if (!$pid) {
                sleep(1);
                print "In child $i\n";
                exit($i);
            }
        }
        
        while (pcntl_waitpid(0, $status) != -1) {
            $status = pcntl_wexitstatus($status);
            echo "Child $status completed\n";
        }

结果:
In child 1
In child 2
In child 4
In child 3
In child 5
Child 2 completed
Child 4 completed
Child 3 completed
Child 1 completed
Child 5 completed

$childs = array();

// Fork some process.
for($i = 0; $i < 10; $i++) {
    $pid = pcntl_fork();
    if($pid == -1)
        die('Could not fork');

    if ($pid) {
        echo "parent \n";
        $childs[] = $pid;
    } else {
        // Sleep $i+1 (s). The child process can get this parameters($i).
        //sleep($i+1);
        echo "i=$i \n";
        // The child process needed to end the loop.
        exit();
    }
}

while(count($childs) > 0) {
    foreach($childs as $key => $pid) {
        $res = pcntl_waitpid($pid, $status, WNOHANG);
        
        // If the process has already exited
        if($res == -1 || $res > 0)
            unset($childs[$key]);
    }
    
    sleep(1);
}

结果:
parent
parent
i=0
i=1
parent
parent
i=3
parent
parent
parent
parent
parent
parent
i=4
i=2
i=8
i=9
i=7
i=5
i=6

发表评论

电子邮件地址不会被公开。 必填项已用*标注


*