Join 4,000+ others and never miss out on new tips, tutorials, and more.
Latest version:
pecl install openswoole-22.1.2 | composer require openswoole/core:22.1.5
<?php OpenSwoole\Coroutine\System::waitSignal(int $signalNum, float $timeout = -1): bool
The Linux signal type, this can be something like SIGTERM
, SIGKILL
etc. The specified signal is what the process will wait for until the signal is triggered.
A float in seconds defining how long the process should wait before giving up and returning control. Because a float is used, it means that 2.5 is 2.5 seconds. Minimum value is 0.001 and the default -1 means to never time out, wait for the other process to finish.
Returns true
when the specified signal is received and false
when the signal was not received or if it timed out.
Wait for a process to finish based on the specified signal type, until the signal type is received, the parent process will wait, allowing you to listen for a specific signal.
To learn more about Linux signal types, checkout this post as there are a whole range of different signals for different situations.
As an alternative you can use OpenSwoole\Process::signal
but the pcntl_signal
function should NOT be used within a coroutine context, it is not supported.
Using SIGUSR1 to kill the main process
<?php
use OpenSwoole\Process;
use OpenSwoole\Coroutine;
use OpenSwoole\Coroutine\System;
// Get the main thread process ID
$pid = getmypid();
// Create the process only outside a coroutine
$process = new OpenSwoole\Process(function() use ($pid)
{
echo "Child process start.\n";
sleep(1);
// Send a signal to kill the main process but let the process handle the kill event...
OpenSwoole\Process::kill($pid, SIGUSR1);
echo "Child process exit.\n";
});
// Begin the process
$process->start();
// Entering a coroutine context
co::run(function()
{
// Wait for a user defined kill signal to handle, wait 3 seconds at max
$info = OpenSwoole\Coroutine\System::waitSignal(SIGUSR1, 3);
var_dump($info);
});
Output:
Child process start
Child process exit
bool(true)
The above code works and does not kill the parent before it can wait for the signal because the kill signal SIGUSR1
allows us to handle the kill event. The signal SIGUSR1
is used for when you want to allow the process to handle the signal event itself, so in our example, the main process can wait for the signal to be triggered. Allowing a developer to write their own signal handler.
Using SIGUSR1 to kill the child process from the main process
<?php
use OpenSwoole\Process;
use OpenSwoole\Coroutine;
use OpenSwoole\Coroutine\System;
// Creating the process outside of a coroutine
$process = new Process(function()
{
// Using a coroutine context inside of a child process
co::run(function()
{
echo "Inside child process...\n";
// Signal handler
$status = System::waitSignal(SIGUSR1);
var_dump($status);
echo "End of child process.\n";
});
});
// Start the child process...
$process->start();
sleep(1);
echo "Sending kill signal to child process...\n";
// Send a signal to the child process but let it handle the event using SIGUSR1
OpenSwoole\Process::kill($process->pid, SIGUSR1);
echo "End of main process.\n";
Output:
Inside child process...
Sending kill signal to child process...
End of main process.
bool(true)
End of child process.
Again this works because the kill signal SIGUSR1
allows us to use our own custom signal handler. If no handler is set then the process will just be terminated, that is why the waitSignal
call is important. The main process does not use a co::run
coroutine container because it is not needed in this example but you could use one if you wanted, just make sure to pass in the $process
object so it has access to it.