PHP.mk документација

pcntl_alarm

Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.

function.pcntl-alarm.php PHP.net прокси Преводот се освежува
Оригинал на PHP.net
Патека function.pcntl-alarm.php Локална патека за оваа страница.
Извор php.net/manual/en Оригиналниот HTML се реупотребува и локално се стилизира.
Режим Прокси + превод во позадина Кодовите, табелите и белешките остануваат читливи во истиот тек.
pcntl_alarm

Референца за `function.pcntl-alarm.php` со подобрена типографија и навигација.

function.pcntl-alarm.php

pcntl_alarm

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

pcntl_alarmПостави будилник за доставување сигнал

= NULL

pcntl_alarm(int $seconds): int

Креира тајмер што ќе испрати SIGALRM сигнал до процесот по дадениот број на секунди. Секое повикување на pcntl_alarm() ќе откаже кој било претходно поставен аларм.

Параметри

seconds

Бројот на секунди за чекање. Ако seconds е нула, не се креира нов аларм.

Вратени вредности

Враќа време во секунди што било кој претходно закажан аларм го имал преостанато пред да биде доставен, или 0 ако немало претходно закажан аларм.

Белешки од корисници 4 белешки

Рајан Џентцш
пред 5 години
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;
Рајан Џентцш
3 години пред
Keep in mind that you can easily and selectively prevent signal types of your choosing (including SIGALRM) from interrupting blocking operations you don't want interrupted. Use pcntl_sigprocmask() to shield any part of your code, whenever needed and without affecting expected signal behavior for the rest of it.

Here is simple example of shielding one blocking sleep operation from being interrupted while allowing it to happen to another - right next to each other.

<?php
$alarm = 2;
$sleep = 10;
$stamp = time();

pcntl_async_signals(TRUE);

/**
 * Alarm signal handler.
 */
pcntl_signal(SIGALRM, function(int $sig) use ($alarm, &$stamp) {
  $late = (($now = time()) - $stamp) - $alarm;
  $stamp = $now;
  echo '* ALARM SIGNAL HANDLER * Fired '. ($late ? ($late .' seconds late') : 'on schedule') .' *'. PHP_EOL;
  pcntl_alarm($alarm);
});

/**
 * Sleeping function.
 */
function get_some_sleep(int $duration, string $info) {
  $start = time();
  echo PHP_EOL . $duration .' seconds sleep - '. $info . PHP_EOL;
  sleep($duration);
  $early = $duration - (time() - $start);
  echo 'Sleep was '. ($early ? ('interrupted. Woke up '. $early .' seconds early.') : 'uninterrupted.') . PHP_EOL;
}

/**
 * Here we schedule first alarm.
 */
pcntl_alarm($alarm);

while (TRUE) {
  /**
   * This sleep can and will be interrupted by alarm signal.
   */
  get_some_sleep($sleep, 'without a shield');

  /**
   * Now we set our shield. From now on blocked signals will be ignored.
   * Each blocked signal type that fires while shield is up is put on hold.
   */
  pcntl_sigprocmask(SIG_BLOCK, [SIGALRM]);
  get_some_sleep($sleep, 'protected by sigprocmask()');

  /**
   * Now we take off our shield. If any blocked signal fired while shield
   * was up now it's handler will be executed immediately, single time.
   * This is very useful behaviour because we protect what needs protecting but also
   * don't miss out on anything - without being flooded thanks to "once per type" queue.
   */
  pcntl_sigprocmask(SIG_UNBLOCK, [SIGALRM]);
}
Гао, Шенгвеи
пред 7 години
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);
}
molsavsky1 на gmail точка ком
пред 4 години
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;
```
На оваа страница

Автоматски outline од активната документација.

Насловите ќе се појават тука по вчитување.

Попрегледно читање

Примерите, changelog табелите и user notes се визуелно издвоени за да не се губат во долгата содржина.

Брз совет Користи го outline-от Скокни директно на главните секции од активната страница.
Извор Оригиналниот линк останува достапен Кога ти треба целосен upstream context, отвори го PHP.net во нов tab.