@HellWalk

Что изменяет работу pcntl_fork в PHPUnit?

Возьмем чистый php скрипт со следующим кодом:

$sleep = 3;
$pid = pcntl_fork();

if ($pid === -1) {
    echo 'Не удалось породить дочерний процесс' . PHP_EOL;
    die();
}

if ($pid) {
    echo 'PID: ' . $pid . PHP_EOL;
    echo "Ожидаем $sleep секунды и убиваем дочерний процесс" . PHP_EOL;
    sleep($sleep);
    echo 'Убиваем дочерний процесс' . PHP_EOL;
    posix_kill($pid, SIGKILL);
    echo 'End' . PHP_EOL;
} else {
    echo '[Дочерний код работает]' . PHP_EOL;
    sleep(300);
}


Выполнив его мы получим следующий результат:


PID: 57237
Ожидаем 3 секунды и убиваем дочерний процесс
[Дочерний код работает]
Убиваем дочерний процесс
End


После этого, создадим простой unit-тест с аналогичным кодом:

public function testFork(): void
    {
        $sleep = 3;
        $pid = pcntl_fork();

        if ($pid === -1) {
            echo 'Не удалось породить дочерний процесс' . PHP_EOL;
            die();
        }

        if ($pid) {
            echo 'PID: ' . $pid . PHP_EOL;
            echo "Ожидаем $sleep секунды и убиваем дочерний процесс" . PHP_EOL;
            sleep($sleep);
            echo 'Убиваем дочерний процесс' . PHP_EOL;
            posix_kill($pid, SIGKILL);
            echo 'End' . PHP_EOL;
        } else {
            echo '[Дочерний код работает]' . PHP_EOL;
            sleep(300);
        }
    }


Выполняем его и получаем:


PID: 57335
Ожидаем 3 секунды и убиваем дочерний процесс
Убиваем дочерний процесс
End


Как видно - дочерний процесс не отработал. Собственно вопрос - что в phpunit изменяет работу с форками процессов?
  • Вопрос задан
  • 55 просмотров
Решения вопроса 1
@neol
phpunit буферизует вывод и эта буферизация не готова к многопоточности. Ваш поток работает, просто вывод теряется. Если отключить буферизацию, то взлетит:

ob_end_flush();
if ($pid) {
    echo 'PID: ' . $pid . PHP_EOL;
    echo "Ожидаем $sleep секунды и убиваем дочерний процесс" . PHP_EOL;
    sleep($sleep);
    echo 'Убиваем дочерний процесс' . PHP_EOL;
    posix_kill($pid, SIGKILL);
    echo 'End' . PHP_EOL;
} else {
    echo '[Дочерний код работает]' . PHP_EOL;
    sleep(300);
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы