gpt4 book ai didi

php - pcntl_sigwaitinfo 和信号处理程序

转载 作者:可可西里 更新时间:2023-10-31 23:22:53 26 4
gpt4 key购买 nike

我正在编写一个守护进程,它周期性地做一些工作并休眠一段时间,然后再重复它。但它在 sleep 时仍必须对外部影响(即终止请求)做出响应。

我设法通过 ALRM 信号实现 sleep 超时并通过 TERM 信号实现终止(示例):

// ...

declare(ticks = 1);

function do_work()
{
echo "Doing some work.\n";
}

$term = FALSE;

$sighandler = function ($signal) use (&$term)
{
if ($signal === SIGTERM)
{
pcntl_alarm(0);

$term = TRUE;

echo "TERM HANDLER\n";
} else {
echo "ALRM HANDLER\n";
}
};

pcntl_signal(SIGALRM, $sighandler);
pcntl_signal(SIGTERM, $sighandler);

while (!$term)
{
do_work();

// Kick myself after 2 seconds
pcntl_alarm(2);

// Wait for alarm or termination
$signal = pcntl_sigwaitinfo(array(SIGTERM, SIGALRM), $info);

pcntl_signal_dispatch();

switch ($signal)
{
case SIGALRM: echo "ALRM SIGWI\n"; break;
case SIGTERM: echo "TERM SIGWI\n"; $term = TRUE; break;
}
}

// ...

但是看在上帝的份上,我不明白为什么 sighandler 从未被调用过。我得到以下输出:

$ php sigsample.php
Doing some work.
ALRM SIGWI
Doing some work.
ALRM SIGWI
Doing some work.
TERM SIGWI

同时,如果我不设置此处理程序,脚本会因为未处理程序信号而终止。

我错过了什么吗?为什么我的信号处理函数从未被调用过?是不是 pcntl_sigwaitinfo() 干扰了?

还有没有其他方法可以同时实现超时和信号处理?

最佳答案

这并不完全出乎意料。

您已要求将信号传递给信号处理程序 (pcntl_signal(...)),但随后又要求在不调用任何处理程序的情况下接受信号 (pcntl_sigwaitinfo(... ))。您的操作系统将决定在这种情况下会发生什么,并且您的操作系统(例如我的操作系统)选择让 pcntl_sigwaitinfo() 获胜。

背景

进程可以通过两种不同的方式接收(“遭受?”)信号:

  1. 异步交付

    信号会引发一些异步操作,通常是终止进程或调用用户定义的处理程序。 pcntl_signal注册这样的处理程序。

    C 程序员熟悉的底层调用是 signalsigaction .

  2. 同步接受

    特殊的系统函数注意到一个信号处于挂起状态,并将其从挂起列表中删除,并将有关该信号的信息返回给进程。 pcntl_sigwaitinfo就是这样一个函数。

    底层调用是 sigwait , sigwaitinfosigtimedwait .

这两种方式,交付接受,是different不能一起使用。例如,AIX 只是禁止 "[c]oncurrent use of sigaction and sigwait" .

(与上述相关的是信号掩码的概念,它可以“阻塞”信号,有效地迫使它们保持挂起状态,直到被接受或直到“解除阻塞”并交付。)

关于php - pcntl_sigwaitinfo 和信号处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12826297/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com