PHP 8.1.2 Released!

pcntl_alarm

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

pcntl_alarmBelli bir süre sonra SIGALRM sinyali gönderir

Açıklama

pcntl_alarm(int $saniye): int

saniye ile belirtilen sürenin sonunda sürece bir SIGALRM sinyali gönderir. Yapılan her pcntl_alarm() çağrısı bir öncekini geçersiz kılar.

Değiştirgeler

saniye

Sinyal gönderilene kadar beklenecek süre. Sıfır belirtilirse hiçbir sinyal gönderilmez.

Dönen Değerler

Devreye girmeden geçersiz hale getirilmiş önceki çağrının süresini döndürür. Böyle bir çağrı yoksa 0 döner.

add a note add a note

User Contributed Notes 3 notes

up
15
kuba at valentine dot dev
1 year ago
This is that universal timeout functionality you dreamed about and always wanted to have and guess what - it's as reliable as it gets, it's basically bulletproof. It can interrupt absolutely anything you throw at it and more, you name it - socket_connect(), socket_read(), fread(), infinite while() loops, sleep(), semaphores - seriously, any blocking operation. You can specify your own handler and just get over anything that normally would make your code unresponsive.

<?php
/**
* Because we shouldn't handle asynchronous
* events in synchronous manner.
*/
pcntl_async_signals(TRUE);

/**
* Some flag we can change to know for sure
* that our operation timed out.
*/
$timed_out = FALSE;

/**
* Register SIGALRM signal handler to avoid
* getting our process killed when signal arrives.
*/
pcntl_signal(SIGALRM, function($signal) use (&$timed_out) {
 
$timed_out = TRUE;
});

/**
* Now we set our timeout for 2 seconds, but it's not set in stone
* we can call pcntl_alarm() anytime to extend or to turn if off.
*/
pcntl_alarm(2);

/**
* Here we do something with unpredictable outcome that could
* possibly block our program for a very long time.
* I like sockets as an example, but it can be anything.
*/
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$connection = socket_connect($socket, 'irc.ircnet.com', 6667);

/**
* If our blocking operation didn't timed out then
* timer is still ticking, we should turn it off ASAP.
*/
$timed_out || pcntl_alarm(0);

/**
* And now we do whatever we want to do.
*/
$status = $connection ? 'Connected.' : ($timed_out ? 'Timed out.' : socket_strerror(socket_last_error($socket)));
echo
'STATUS: '. $status . PHP_EOL;
up
0
molsavsky1 at gmail dot com
1 month ago
Beware that pcntl_signal will interrupt (u)sleep calls which will not be resumed once the handler is completed.

It's a documented behaviour (https://www.php.net/manual/en/function.sleep.php) although it may look like a bug when encountered for the first time.

From the docs:
"If the call was interrupted by a signal, sleep() returns a non-zero value. On Windows, this value will always be 192 (the value of the WAIT_IO_COMPLETION constant within the Windows API). On other platforms, the return value will be the number of seconds left to sleep."

```
<?php

$interval
= 1;
pcntl_async_signals(true);

pcntl_signal(SIGALRM, function () use ($interval): void {
    echo
'SIGALRM called' . PHP_EOL;
   
pcntl_alarm($interval);
});

pcntl_alarm($interval);

echo
'Sleep (will be interrupted) started' . PHP_EOL;

sleep(100000000000);

echo
'Sleep ended soon due to interrupt' . PHP_EOL;

$sleepTimeout = 10;
echo
"Proper sleep for {$sleepTimeout} seconds" . PHP_EOL;

$startedAt = time();
while (
$sleepTimeout > 0 && ($sleepTimeout = sleep($sleepTimeout)) !== true) {
    echo
"Sleep interrupted, {$sleepTimeout} seconds remaining" . PHP_EOL;
}

$elapsed = time() - $startedAt;
echo
"Sleep finished after {$elapsed} seconds" . PHP_EOL;
```
up
-3
Gao,Shengwei
3 years ago
Use pcntl_signal_dispatch() to catch the signal, don't use declare(ticks=1) because it is ineffcient

<?php
pcntl_signal
(SIGALRM, function () {
    echo
'Received an alarm signal !' . PHP_EOL;
},
false);

pcntl_alarm(5);

while (
true) {
   
pcntl_signal_dispatch();
   
sleep(1);
}
To Top