如何创建多个子进程

wuxian
$socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
socket_set_nonblock($socket);
socket_bind($socket,'0.0.0.0',8666) or die('error');
socket_listen($socket,10);
$sockets = ;
$sockets = $socket;
while(true) {
    for ($i = 0; $i < 5; $i++) {
        $pid = pcntl_fork();
        echo $pid;
        if ($pid == -1) {
            die('could not fork');
        } else if ($pid) {
            pcntl_wait($status); //等待上一个进程结束
        } else {
            $clients = $sockets;
            socket_select($clients, $write, $except, NULL);
            foreach ($clients as $n=>$v) {
                if ($v == $socket) {
                    $client = socket_accept($socket);
                    $clients = $client;
                }else{
                $buf = socket_read($v, 1024);

                    if (preg_match('/sleep/i', $buf)) {
                        $html = 'HTTP/1.1 200 OK' . PHP_EOL
                            . 'Content-Type: text/html;charset=utf-8' . PHP_EOL . PHP_EOL;
                        socket_write($v, $html);
                        socket_write($v, "this is server,45434");
                    } else {
                        socket_write($v, "this is server");
                    }
                    unset($clients);
                    socket_close($v);
                    exit;//关闭子进程

}
            }
        }
    }
}

socket_close($socket); 

这样创建完之后,只有一个子进程 

3391 3 0
3个回答

blogdaren

1、题示的写法,在创建了第一个子进程后,因为pcntl_wait系统调用会阻塞主进程。
2、进程部分参考代码:

<?php
for ($i = 0; $i < 5; $i++) 
{
    $pid = pcntl_fork();
    echo $pid . PHP_EOL;
    if($pid < 0) {
        die('could not fork');
    }elseif($pid > 0) {
    }else{
        while(1){sleep(1);}
        exit;
    }
}

while(1)
{
    pcntl_wait($status);
}
  • 暂无评论
wuxian

感谢大神解答,但有疑惑,pcntl_wait($status); 我的写法是写在主进程执行的代码,也会阻塞子进程吗,

  • blogdaren 2019-03-20

    写在主程会阻塞主程,不会阻塞子进程。

wuxian

$socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
socket_set_nonblock($socket);
socket_bind($socket,'0.0.0.0',8666) or die('error');
socket_listen($socket,10);
$sockets = $socket;
while(true) {
for ($i = 0; $i < 5; $i++) {
$pid = pcntl_fork();
echo $pid;
if ($pid == -1) {
die('could not fork');
} else if ($pid) {

    } else {
        $clients = $sockets;
        socket_select($clients, $write, $except, NULL);
        foreach ($clients as $n=>$v) {
            if ($v == $socket) {
                $client = socket_accept($socket);
                $clients = $client;
            }else{
                $buf = socket_read($v, 1024);

                if (preg_match('/sleep/i', $buf)) {
                    $html = 'HTTP/1.1 200 OK' . PHP_EOL
                        . 'Content-Type: text/html;charset=utf-8' . PHP_EOL . PHP_EOL;
                    socket_write($v, $html);
                    socket_write($v, "this is server,45434");
                } else {
                    socket_write($v, "this is server");
                }
                unset($clients);
                socket_close($v);
                exit;//关闭子进程

            }
        }
    }
}
while(1){
    pcntl_wait($status); //等待上一个进程结束
}

}

socket_close($socket);
 这样改写之后,创建了不只5个进程 ,是5个子进程,但每个子进程又有子进程

  • blogdaren 2019-03-20

    1、外层的while死循环纯属多余;
    2、子进程部分关于select 复用部分的实现代码也是有问题的;【这部分代码是导致子进程创建混乱的原因根本所在】
    3、另外注意信号处理机制;

  • blogdaren 2019-03-20

    我再补充两点,具体的代码怎么写,自己琢磨了:
    1、外层的死循环应该是写在子进程内;
    2、子进程之所以创建异常,是因为子进程select实现代码存在问题,导致fork以克隆的副本角色在子进程内执行。

  • wuxian 2019-03-21

    谢谢大神指点

年代过于久远,无法发表回答
🔝