草庐IT

PHP sleep 、pcntl_signal 和滴答声

coder 2024-04-22 原文

好的,所以我一直在尝试获取 Process Signals使用 PHP 脚本。我遇到了很多我不确定发生了什么的事情,而且我觉得文档没有很好地解释它。

假设我按照 registering signals 上的示例进行操作:

<?php
// tick use required as of PHP 4.3.0
declare(ticks = 1);

// signal handler function
function sig_handler($signo)
{

     switch ($signo) {
         case SIGTERM:
             // handle shutdown tasks
             exit;
             break;
         case SIGHUP:
             // handle restart tasks
             break;
         case SIGUSR1:
             echo "Caught SIGUSR1...\n";
             break;
         default:
             // handle all other signals
     }

}

echo "Installing signal handler...\n";

// setup signal handlers
pcntl_signal(SIGTERM, "sig_handler");
pcntl_signal(SIGHUP,  "sig_handler");
pcntl_signal(SIGUSR1, "sig_handler");

// or use an object, available as of PHP 4.3.0
// pcntl_signal(SIGUSR1, array($obj, "do_something"));

echo"Generating signal SIGTERM to self...\n";

// send SIGUSR1 to current process id
posix_kill(posix_getpid(), SIGUSR1);

echo "Done\n";

?>

但是,在我的 sig_handler 函数中,我在末尾添加了一个 exit(1)echo "Done\n"; 还会被执行吗?我已经尝试过类似的东西,尽管是在类结构中,而且它只是在 我的 sig_handler 被调用之前。

我的类 __construct 调用函数 registerSignals:

private function registerSignals(){
    if(function_exists("pcntl_signal")){
        //call_user_func([$this, "sigintCleanup"]);
        pcntl_signal(SIGINT, [$this, "sigintCleanup"]);
        pcntl_signal(SIGTERM, [$this, "sigtermCleanup"]);
        pcntl_signal(SIGHUP, [$this, "sighupCleanup"]);
        pcntl_signal(SIGUSR1, [$this, "sigusr1Cleanup"]);
    }
}

protected function sigintCleanup(){
    echo "In SIGINT cleanup\n";
    $this->cleanup();
}

protected function sigtermCleanup(){
    echo "In SIGTERM cleanup\n";
    $this->cleanup();
}

protected function sighupCleanup(){
    echo "In SIGHUP cleanup\n";
    $this->cleanup();
}

protected function sigusr1Cleanup(){
    echo "In SIGUSR1 cleanup\n";
    $this->cleanup();
}

protected function cleanup(){
    echo "Shutting down\n";
    exit(1);
}

然后在我对这个过程的测试中,我做了一些简单的 sleepecho(start 只是一个在之后调用的函数施工和信号注册完成):

function start(){
    echo "-- Testing the test script --\n";
    sleep(10000);
    echo "given how ticks work, this might not be called...\n";
    echo "\nAfter sleep... this should not be executed if there was a signal interrupt.\n";
}

所以我在 sleep 期间使用ctl-c。我的结果?

-- Testing the test script --
^Cgiven how ticks work, this might not be called...

After sleep... this should not be executed if there was a signal interrupt.
In SIGINT cleanup
Shutting down

正如您从我的 echo 中看到的那样,我有点想通了 ticks work 负责处理信号之前完成 start 函数。我仍然认为可能是这种情况。事实上,我只是不知道。

我确实在我的程序顶部声明了 ticks:

declare(ticks = 1);

不立即处理信号给我带来了麻烦。例如,如果我的 start 函数中有这段代码(并且我已经测试过了)怎么办?

$count = 0;
while(true){
    count++;
    echo "count\n";
    sleep(5);
}

即使我的cleanup 函数有一个exit,我也永远不会达到那个,因为SIGINT 只是让我从sleep,我继续循环并再次开始 sleeping。

所以这是我的问题:signal 处理在 PHP 中是如何工作的?如何保证收到信号后立即处理?我不只是想要一些代码来解决这个问题,我想要一个解释(或者至少一个好的解释和摘要的链接)。

PHP 版本:5.4.22

操作系统:Ubuntu 12.10

最佳答案

sleep() 会被一些信号打断,它会返回剩余的 sleep 秒数,你可以做这样的事情让它保持 sleep 。

.....
declare(ticks = 1);

$left = sleep(1000)
while ($left > 0) {
   $left = sleep($left);
}

关于PHP sleep 、pcntl_signal 和滴答声,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23001571/

有关PHP sleep 、pcntl_signal 和滴答声的更多相关文章

  1. javascript - 没有过载匹配此调用。类型 'string' 不可分配给类型 'Signals' - 2

    我正在使用typescript来构建微服务并处理信号。直到几天前,该代码都运行良好,但最近它开始抛出错误。找不到该问题的修复方法。处理信号的代码。它只是文件的一部分。src/main.tsenumsignals{SIGHUP=1,SIGINT=2,SIGTERM=15}constshutdown=(signal,value)=>{logger.warn("shutdown!")Db.closeAll()process.exit(value)}Object.values(signals).forEach(signal=>{process.on(signal,()=>{logger.war

  2. javascript - 我如何在 JavaScript 中生成这种滴答声? - 2

    在a.bestmetronome.com上,他们有一个节拍器可以根据噪音产生滴答声。但是,我无法弄清楚“滴答声”是如何生成的。尽管我能够从Audacity中计算出“滴答”生成器:;;MetronometickbySteveDaulton.(defunmetronome-tick(hzpeak)(let*((ln300)(sig-array(make-arrayln))(x1));;generatesome'predictable'whitenoise(dotimes(iln)(setfx(rem(*479x)997))(setf(arefsig-arrayi)(-(/x500.0)1)

  3. javascript - localhost : how to setup XHR-Signaling (connection. openSignalingChannel 未被调用) - 2

    我正在使用RTCMultiConnectionv3.4.4我想在本地主机上运行WebRTC。我选择了XHR-Signaling,因为我希望项目完全离线。我不希望它依赖于互联网,因为一切都在本地主机上(稍后部署在LAN上)我包含了XHRConnection.js并设置了connection.setCustomSocketHandler(XHRConnection)。我还覆盖了connection.openSignalingChannel...但是,当我打开/启动房间时,我的视频会显示,但被disableInputButtons()禁用的按钮仍然保持禁用状态。聊天不工作。我在覆盖conne

  4. go - panic : runtime error: invalid memory address or nil pointer dereference [signal 0xc0000005 code=0x0 addr=0x8 pc=0x48be5c] goroutine 1 [running]: - 2

    我正在尝试使用链表实现多项式的加法。该程序成功地添加了幂0系数,但在第一次遍历后它出现了困惑。这是我到目前为止编写的代码。在初始化temp1!=nil之后,循环遍历else但当权力不同时不进入if循环并进入panic状态packagemainimport("fmt")typeNodestruct{coefficientintpowerintnext*Node}typeliststruct{head*Nodecountint}funcmain(){list1:=&list{}list1.addVariable(5,2)list1.addVariable(4,1)list1.addVari

  5. linux - 将 os.Signal 转换为字符串以便能够将其打印在文件中 - 2

    我需要将os.signal类型转换为字符串才能将其保存在文件中。err:=ioutil.WriteFile("out",sig,0644)我得到这样的错误:./signals.go:37:cannotusesig(typeos.Signal)astype[]byteinargumenttoioutil.WriteFile 最佳答案 你可以做到err:=ioutil.WriteFile("out",[]byte(sig.String()),0644) 关于linux-将os.Signal转

  6. signals - 有没有办法在向进程发送信号后等待? - 2

    当信号(如os.Interrupt)发送到process时,该过程是否等到完成该过程?或者,我们需要再等一段时间吗? 最佳答案 我想你是在问发送信号是否会等到过程完成?答案是,这取决于平台和您发送的信号类型以及进程对信号的处理方式。一些信号比如Kill无法被捕获,会导致进程终止。除非进程处理它们,否则其他人什么都不做。如果流程不处理它们,还有一些人会做一些事情,但如果它想做一些不同的事情,流程可以处理它。在我进一步了解您的问题之前,这是我能给出的最佳答案。 关于signals-有没有办法

  7. macos - 更新到 macOS beta 4 后,go test -cover 抛出 "fatal error: unexpected signal during runtime execution" - 2

    Gobuild和gotest仍然有效。在更新到macOSbeta之前,我使用测试覆盖工具没有遇到任何问题。“去测试”工作正常;但是,所有覆盖率测试命令都抛出此错误(gotest-coverprofile=coverage.out抛出相同的问题)。如果有人知道如何解决这个问题,我将不胜感激!$gotest-covergobuildgithub.com/hunteramericano/ErrorQuiver:/usr/local/Cellar/go/1.6.3/libexec/pkg/tool/darwin_amd64/cover:signal:fatalerror:unexpecteds

  8. signals - 是否可以以 "defer"方式捕获 Ctrl+C 信号 (SIGINT) 并运行清理功能? - 2

    我想捕获从控制台发送的Ctrl+C(SIGINT)信号并打印出一些部分运行总计。 最佳答案 您可以使用os/signal处理传入信号的包。Ctrl+C是SIGINT,因此您可以使用它来捕获os.Interrupt。c:=make(chanos.Signal,1)signal.Notify(c,os.Interrupt)gofunc(){forsig:=rangec{//sigisa^C,handleit}}()您使程序终止和打印信息的方式完全取决于您。 关于signals-是否可以以"d

  9. windows - 转到异常 "signal arrived during cgo execution" - 2

    在什么情况下Go在调用dll时会出现“signalarrivedduringcgoexecution”之类的panic?要调用的代码是——基于go分发的src中的zsyscall_windows.go中的示例:var(//entrynamesfoundusingdumpbin/exportsdllSweph=syscall.NewLazyDLL("swedll32.dll")_swe_jdut1_to_utc=dllSweph.NewProc("_swe_jdut1_to_utc@36")_swe_julday=dllSweph.NewProc("_swe_julday@24"))fu

  10. windows - 为什么 Windows 7 下的时钟每 6 个慢速滴答显示一个快速滴答声? - 2

    如果你仔细观察windows7下的windows时钟,你会发现每6个慢速滴答声(相同长度)就有一个快速滴答声。我用谷歌搜索,找到一个article告诉windows2K/XP/2K3设置时钟:SetTimer(hWnd,TimerID,OPEN_TLEN,0L);它给出了解释:OPEN_TLENisthelengthofthetimer,itisaconstant.Sowhenwelookatclock.h,youwillgetthenumber,whichis450.Whatdoesthis450mean?Thismeans,every450msthetimerwillbetrigg

随机推荐