Skip to content

SIGCHLD is not always returned from proc_open #11498

Closed
@taka-oyama

Description

@taka-oyama

Description

The following code:

<?php

ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);

// store processes in an array as [$pid => $process, ...]
$processes = [];

// catch signals from child processes and unset processes from the array
pcntl_async_signals(true);
pcntl_signal(SIGCHLD, function($sig, $info) use (&$processes) {
    unset($processes[$info['pid']]);
}, false);

// open 10 processes and store them in an array
foreach (range(0, 10) as $i) {
    $process = proc_open('echo $$', [], $pipes); // prints the pid to STDOUT
    $pid = proc_get_status($process)['pid'];
    $processes[$pid] = $process;
}

// wait for all processes to exit
while(true) {
    echo ' processes remaining:' . count($processes) . PHP_EOL;
    if (empty($processes)) {
        break;
    }
    sleep(1);
}

// Check that all processes have been removed.
var_dump($processes);

Resulted in this output:

921
922
 processes remaining:9
925
926
924
 processes remaining:8
923
 processes remaining:6
931
929
927
 processes remaining:5
928
930
 processes remaining:2
 processes remaining:2
 processes remaining:2
 processes remaining:2
 processes remaining:2
 processes remaining:2
 processes remaining:2
 ...

But I expected this output instead:

837
838
 processes remaining:10
842
840
 processes remaining:8
 processes remaining:7
846
841
 processes remaining:6
847
 processes remaining:5
 processes remaining:4
839
843
 processes remaining:3
844
 processes remaining:1
845
 processes remaining:0
array(0) {
}

There were some rare cases where the script would exit with code 255 with no errors.

root@c09c0fa26c4d:/app# php test.php
933
934
936
 processes remaining:8
937
935
 processes remaining:7
938
939
941
 processes remaining:5
940
942
943
root@c09c0fa26c4d:/app# echo $?
255

PHP Version

PHP 8.2.7 (cli) (built: Jun 13 2023 23:05:53) (NTS)

Operating System

Debian GNU/Linux 12

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions