1

Изучаю fork в php и вот проблема не могу вернуть из функции которую форкаю в массив к примеру, чтоб потом работать с этими данными

<?php
function shell_ls($row)
{
    echo $row . "\n" . shell_exec('ls /tmp');
}

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

Этот код работает и пишет сразу в консоль, как заставить функцию shell_ls возвращать значения

function shell_ls($row)
{
    return $row . "\n" . shell_exec('ls /tmp');
}

а под $pid замутить добавление в массив

if (!$pid) {
    $result[]=shell_ls($i);
    exit($i);
}

ну и соответственно вывести результат в конце выполнения fork()

print_r($result);
1
  • 1
    pcntl_fork - это создание нового процесса (насколько понимаю, не треда, а именно процесса), поэтому придется задействовать тот или иной вид IPC - что бы не делалось в форке, это уже осуществляется вне текущего процесса, он не имеет доступа. Проще всего перед форком создавать уникальный ключ, по которому в базу данных скидывать результаты, и после отработки всех форков эти данные из БД подтягивать, если есть возможность - использовать пайпы или вообще proc_open.
    – etki
    2 мар 2014 в 23:15

1 ответ 1

1

Столкнулся с многопроцессорностью при изучении сокетов в php, там есть примерно такой текст:

list($pid, $master, $workers) = $this->spawnWorkers(); //создаём дочерние процессы

    if ($pid) {//мастер
            fclose($server);//  мастер не будет обрабатывать входящие соединения на основном сокете
            //$masterclass=
            $WebsocketMaster = new WebsocketMasterHandler($workers);//мастер будет пересылать сообщения между воркерами
            $WebsocketMaster->start();
    } else {//воркер
            //$this->log("start worker with $server, $master");
            $WebsocketHandler = new WebsocketWorkerHandler($server, $master);
            $WebsocketHandler->start();
    }

        function spawnWorkers(){

        $master = null;
        $workers=[];
        $i=0;
        while ($i < $this->config['workers']) {
                $i++;
                //создаём парные сокеты, через них будут связываться мастер и воркер
                $pair = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
                $pid = pcntl_fork();//создаём форк
                if ($pid == -1) {
                        die("error: pcntl_fork\r\n");
                } elseif ($pid) { //мастер
                        //$this->log('i will be master');
                        fclose($pair[0]);
                        $workers[$pid] = $pair[1];//один из пары будет в мастере
                } else { //воркер
                        //$this->log('i will be slave');
                        fclose($pair[1]);
                        $master = $pair[0];//второй в воркере
                        break;
                }
            }
            if(!$this->config['workers']){
                $pair = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
                list($pid, $master, $workers) = [0,$pair[0],[$pair[1]]];
                }
            return array($pid, $master, $workers);
        }

Родитель создаёт ($this->config['workers']) воркеров и общается с ними данными, запакованными json через созданные сокеты, переданные в контроллеры мастера и воркеров через $workers и $master соответственно, а $server создаётся до приведённого кода через stream_socket_server - это коннект, который слушают все воркеры и принимают через него клиентские соединения... сама статья тут

Ваш ответ

By clicking “Отправить ответ”, you agree to our terms of service and acknowledge you have read our privacy policy.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками или задайте свой вопрос.