国产+高潮+在线,国产 av 仑乱内谢,www国产亚洲精品久久,51国产偷自视频区视频,成人午夜精品网站在线观看

關(guān)于pcntl_wait與信號中斷觸發(fā)的問題

顆粒Cc.

請教一下,在workerman發(fā)送信號SIGINT給主進程,主進程(pcntl_wait)會立刻收到信號并執(zhí)行信號處理函數(shù),
我模擬了下,主進程(pcntl_wait)會一直阻塞,并不會立刻執(zhí)行信號處理函數(shù),信號已經(jīng)注冊入隊列當(dāng)中了。假設(shè)我發(fā)送了好幾次信號,最終如果按control+c中斷的時候,就會輸出這幾次信號的處理函數(shù)。

首先感謝BOSS:),希望知道workerman是如何處理的,我看了好多次,還是找不出所以然-。-,太笨了。

代碼如下

    function stopAll($sig){
    echo "master has a sig $sig\n" ;
    global $pid ;
    echo $pid."\n" ;
    if($pid > 0) {
        posix_kill($pid,$sig) ;
    }
}

$pid = pcntl_fork();
if($pid > 0)
{
    pcntl_signal(SIGINT,'stopAll') ;
    $epid = pcntl_wait($status,WUNTRACED);
    $id = getmypid();
    echo "parent process {$id}, child process {$pid}\n";
    if($epid){
        echo "child $epid exit \n" ;
    }
    pcntl_signal_dispatch();
}
else
{
       $id = getmypid();
    echo "child process,pid {$id}\n";
    while(1){
        sleep(2) ;
    }
}

我發(fā)送了好幾次信號,仍然阻塞,最后以control+c中斷輸出如下:

qmoredeMacBook-Pro:120.25.105.202 Qmore$ php recive_sig.php 
child process,pid 24793
^[[A^Cmaster has a sig 2
24793
master has a sig 2
24793
master has a sig 2
24793
master has a sig 2
24793
master has a sig 2
24793
parent process 24792, child process 24793
child 24793 exit 
8465 9 0
9個回答

walkor 打賞
else
{
    $id = getmypid();
    echo "child process,pid {$id}\n";
    while(1){
        sleep(2) ;
        pcntl_signal_dispatch();
    }
}

需要在子進程部分及時檢查信號并處理,加一句pcntl_signal_dispatch就好了。
信號回調(diào)不會自己自動執(zhí)行的,要么有聲明declare(ticks=1)要么調(diào)用主動pcntl_signal_dispatch檢查信號。

顆粒Cc.

因為主進程阻塞在pcntl_wait,除非是子進程退出,那么主進程才會繼續(xù)下一步,才有可能主動pcntl_signal_dispatch檢查信號。如果發(fā)送信號給主進程,主進程還是阻塞在pcntl_wait呢,沒法觸發(fā)pcntl_signal_dispatch.>.<

  • 暫無評論
walkor 打賞

pcntl_wait其實就是wait系統(tǒng)調(diào)用,是可以被信號打斷的,當(dāng)信號到來后pcntl_wait會立刻返回。
同理sleep也是系統(tǒng)調(diào)用,也可以被信號打斷停止睡眠立刻返回。
所以在pcntl_wait或者sleep下的pcntl_signal_dispatch函數(shù)在收到信號后會立刻被執(zhí)行。

  • hk2018 2019-12-14

    echo posix_getpid().PHP_EOL;
    pcntl_async_signals(true);

    pcntl_signal(SIGINT, function(){
    echo posix_getpid()." get signal ".date("H:i:s")."\n";

    });

    $pid = pcntl_fork();

    if ($pid) {
    E:
    pcntl_wait($status, WUNTRACED);
    echo pcntl_strerror(pcntl_get_last_error())." pcntl_wait return\n";
    //被信號打斷
    if(pcntl_get_last_error()==4){
    goto E;
    }
    } else {
    echo "son:".posix_getpid().PHP_EOL;
    $i=0;
    while(1){
    echo date("H:i:s").PHP_EOL;
    sleep(1);
    $i++;
    if($i>5){
    exit(100);
    }
    }
    }

    這段代碼在pcntl_signal 不傳第3個參數(shù)時,子進程的sleep會被信號打斷,父進程的wait為啥不會被打斷呢?只是把信號加入隊列

  • hk2018 2019-12-14

    php是7.3版本的

顆粒Cc.

恩恩,我就是這點疑惑,我利用另外的一個程序,像主進程發(fā)送了SIGINT信號,但是他并不會被打斷,只會將信號加入信號隊列。

  • 暫無評論
顆粒Cc.

我再去理解理解,多謝boss

  • 暫無評論
walkor 打賞

不客氣

  • 暫無評論
soooldier

看了下兩位的回復(fù),感覺其中是有問題的。樓主的問題是“在workerman發(fā)送信號SIGINT給主進程,主進程(pcntl_wait)會立刻收到信號并執(zhí)行信號處理函數(shù)”,而在示例代碼中的邏輯比較混亂。在walkor給出的答案里說到了子進程添加pcntl_signal_dispatch(),但是注冊信號回調(diào)的代碼缺是在主進程。最后貼一下描述“在workerman發(fā)送信號SIGINT給主進程,主進程(pcntl_wait)會立刻收到信號并執(zhí)行信號處理函數(shù)”的代碼,如有不正確的地方請多多指教:

function stopAll($sig){
    echo "master has a sig $sig\n" ;
}

$master_id = getmypid();

$pid = pcntl_fork();
if($pid > 0)
{
    pcntl_signal(SIGINT,'stopAll') ;
    $epid = pcntl_wait($status,WUNTRACED);
    pcntl_signal_dispatch();
    echo "parent process {$master_id}, child process {$pid}\n";
    if($epid){
        echo "child $epid exit \n" ;
    }
}
else
{
    $id = getmypid();
    echo "child process,pid {$id}\n";
    sleep(6);
    echo "send signal to master\n";
    posix_kill($master_id, SIGINT);
}
  • sunshine 2016-11-08

    不錯哦

  • sunshine 2016-11-08

    可是上面的例子中pcntl_signal_dispatch()注釋掉的話,也是正常的。為什么要在這個位置添加呢?

  • 張若初 2020-10-28

    經(jīng)測試,主進程是在子進程退出后收到的信號,該改動無效

walkor 打賞

最后貼一下描述“在workerman發(fā)送信號SIGINT給主進程,主進程(pcntl_wait)會立刻收到信號并執(zhí)行信號處理函數(shù)”的代碼,如有不正確的地方請多多指教:

對的

  • soooldier 2016-10-09

    請教一下walkor大俠,pcntl_wait第二個參數(shù)WUNTRACED具體表示什么意思呢?手冊里的解釋沒太看懂

張若初

最終的解決辦法是在pcntl_signal()的第三個參數(shù),設(shè)置未false,也就是說,系統(tǒng)調(diào)用不自動重新啟動,可以收到信號,這個不理解

  • phpcreeper 2020-10-29

    設(shè)置為true的話,wait會再次被自動調(diào)用,導(dǎo)致進程再次阻塞;另外一次信號只能中斷一次系統(tǒng)調(diào)用。

年代過于久遠,無法發(fā)表回答
??