請記住,您可以輕鬆且有選擇地阻止您選擇的信號類型(包括 SIGALRM)中斷您不希望被中斷的阻塞操作。 使用 pcntl_sigprocmask() 在需要時屏蔽您的任何程式碼區塊,而不會影響其餘程式碼的預期信號行為。
以下是一個簡單的例子,說明如何屏蔽一個阻塞的 sleep 操作不被中斷,同時允許另一個阻塞的 sleep 操作被中斷 - 它們彼此相鄰。
<?php
$alarm = 2;
$sleep = 10;
$stamp = time();
pcntl_async_signals(TRUE);
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);
});
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;
}
pcntl_alarm($alarm);
while (TRUE) {
get_some_sleep($sleep, 'without a shield');
pcntl_sigprocmask(SIG_BLOCK, [SIGALRM]);
get_some_sleep($sleep, 'protected by sigprocmask()');
pcntl_sigprocmask(SIG_UNBLOCK, [SIGALRM]);
}