请记住,您可以轻松且选择性地阻止您不想中断的阻塞操作中断了您选择的信号类型(包括 SIGALRM)。使用 pcntl_sigprocmask() 来保护任何部分的代码,无论何时需要,都不会影响其剩余部分的预期信号行为。
这是一个屏蔽一个阻塞睡眠操作免受中断,同时允许它发生在另一个阻塞睡眠操作旁边的简单示例。
<?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 '* 闹钟信号处理程序 * 触发'. ($late ? ($late .' 秒延迟') : '按计划') .' *'. PHP_EOL;
pcntl_alarm($alarm);
});
function get_some_sleep(int $duration, string $info) {
$start = time();
echo PHP_EOL . $duration .' 秒睡眠 - '. $info . PHP_EOL;
sleep($duration);
$early = $duration - (time() - $start);
echo '睡眠'. ($early ? ('被中断。提前 '. $early .' 秒醒来。') : '未中断。') . PHP_EOL;
}
pcntl_alarm($alarm);
while (TRUE) {
get_some_sleep($sleep, '没有屏蔽');
pcntl_sigprocmask(SIG_BLOCK, [SIGALRM]);
get_some_sleep($sleep, '受 sigprocmask() 保护');
pcntl_sigprocmask(SIG_UNBLOCK, [SIGALRM]);
}