Open alex-rsk opened 5 days ago
Because you haven't provided the complete code, I'm not very clear about the entire execution flow. This error occurs because you executed code similar to the one below, where you listen for the SIGCHLD signal while using a blocking function. Thus, when the parent process receives the SIGCHLD signal, it blocks the current coroutine. Therefore, you need to rewrite the code to use the non-blocking function System::wait to monitor the child process exit.
<?php
use Swoole\Coroutine;
use Swoole\Coroutine\System;
use Swoole\Process;
Process::signal(SIGCHLD, function(){});
$process = new Process(function () {
echo 'Hello';
});
$process->start();
Coroutine\run(function () use ($process) {
System::exec('ls -al'); // The signal [SIGCHLD] is registered, cannot execute swoole_coroutine_exec
});
try
<?php
use Swoole\Coroutine;
use Swoole\Coroutine\System;
use Swoole\Process;
$process = new Process(function () {
echo 'Hello';
});
$process->start();
Coroutine\run(function () use ($process) {
System::exec('ls -al');
$status = System::wait(); // wait child process exit
assert($status['pid'] === $process->pid);
var_dump($status);
});
We work together. Here is an example of the code. Try this
test.php
<?php
while(1) {
echo 'hi'.PHP_EOL;
sleep(1);
}
main.php
<?php
use function Swoole\Coroutine\go;
use function Swoole\Coroutine\run;
use Swoole\Process;
$proc = new Process(function (Process $process) {
$process->exec('php',['test.php']); //set your abs php
},1,1);
$proc->start();
run(function() use ($proc) {
HandleSignals();
go(function () use ($proc) {
$sock = $proc->exportSocket();
while(1) {
$data = $sock->recvLine(timeout: 1);
if(empty($data) ) continue;
echo 'GET '.$data.PHP_EOL;
}
});
go(function() {
$proc = proc_open('php test.php',[],$pipes);
if( is_resource($proc) ) {
$status = proc_get_status($proc);
echo json_encode($status).PHP_EOL;
}
sleep(2);
proc_close($proc);
echo 'closed';
});
});
function HandleSignals() {
Process::signal(SIGTERM, function () {
echo 'TERM'.PHP_EOL;
});
Process::signal(SIGCHLD, function () {
while( $ref = Process::wait(false) ) {
echo json_encode($ref);
}
});
}
A third-party program is running in the $proc variable and it returns information to stderr.
Depending on the response, we have to call various commands via proc_open asynchronously in the coroutine, as seen below.
when we call proc_open, we receive the message: Warning: proc_open(): [SIGCHLD] signal is registered, swoole_proc_open cannot be executed
Please answer these questions before submitting your issue.
1. What did you do? If possible, provide a simple script for reproducing the error.
We are using swoole wrapper LaravelS, but my issue related more to the Swoole per se and IPC, than to specific laravelS problems.
We run Swoole Process, which, in turn, has been launching child processes. As we need to watch falling of these child processes , we set custom handler for SIGCHLD in the parent process. Child processes could call external programs (cat, touch etc). Without SIGCHLD handling in parent process, everything is working good. But after adding SIGCHLD handler, any program cannot start.
Calling external program in child process
touch_launcher
:Estimated result : an external program starts.
Obtained result: Program does not start. We are getting error:
3. What did you expect to see?
An external program (any console utility, like
touch
could be an example) starts.4. What did you see instead?
Program does not start, we are getting error
Swoole\Coroutine::exec(): The signal [SIGCHLD] is registered, cannot execute swoole_coroutine_exec
5. What version of Swoole are you using (show your
php --ri swoole
)?5.1.4
uname -a
&php -v
&gcc -v
) ? Linux Ubuntu 22 x86_64