-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot run external program inside coroutine, when custom SIGCHLD handler was established #5583
Comments
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. 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 |
@grvoyt try <?php
use function Swoole\Coroutine\go;
use function Swoole\Coroutine\run;
use Swoole\Process;
use Swoole\Coroutine\System;
$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';
});
while( $ref = System::wait() ) {
echo json_encode($ref);
}
});
function HandleSignals() {
Process::signal(SIGTERM, function () {
echo 'TERM'.PHP_EOL;
});
} |
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
The text was updated successfully, but these errors were encountered: