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

pcntl_wait調(diào)用問題

back0893

下面是我測試的代碼,我發(fā)現(xiàn)如果在子進程中給父進程發(fā)送一個信號,如果使用pcntl_wait將會等待子進程退出才能執(zhí)行
因為我使用php7.2測試的,所以是php版本導致?
我也看了網(wǎng)站里面的其他提問,冒失父進程都會阻塞到子進程退出

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

$master_id = getmypid();

$pid = pcntl_fork();
if($pid > 0)
{
    pcntl_signal(SIGINT,'stopAll') ;
   pcntl_signal_dispatch();
    $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";
    echo "send signal to master\n";
    posix_kill($master_id, SIGINT);
    sleep(60);
}
5048 3 0
3個回答

back0893

因為我再看源碼,在自己實現(xiàn)給父進程發(fā)送信號時方向,信號會被阻塞到子進程退出才會執(zhí)行,,,,,
em,有點不明白stop是咋個實現(xiàn)的,因為我看源碼也是給父進程發(fā)送一個信號
還是因為我是用cli沒有用守護進程問題?

  • 暫無評論
back0893

還是手冊沒看明白
我知道了 pcntl_signal(SIGINT,'stopAll')
這里需要 添加第三個參數(shù) 默認是true,這樣子進程的sleep就不會執(zhí)行了 pcntl_signal(SIGINT,'stopAll',false) 父進程信號就會被立即執(zhí)行,并且pcntl_wait返回的值是-1

  • 暫無評論
phpcreeper

你雖然找到了關鍵的第三個參數(shù),但是原理部分我認為理解錯了呢,而且示例代碼也是個問題代碼:
1、你說的 "添加第三個參數(shù) 默認是true,這樣子進程的sleep就不會執(zhí)行了", 并不是這樣的,子進程并未退出,而是休眠了,如果你寫的不是sleep,而是死循環(huán),那就成了典型的僵尸進程了【ps aux 或 strace下就會看到真相】
2、信號是可以中斷 wait 等系統(tǒng)調(diào)用的
3、pcntl_signal(SIGINT,'stopAll',false) 函數(shù)的第三個參數(shù)是代表進程在收到信號后是內(nèi)核是否重啟系統(tǒng)調(diào)用。
4、根據(jù)上述條款2理論,示例代碼中設置為false,那么主進程中 pcntl_wait立即被中斷并返回了 -1,這個-1是代表異常出錯了,而出錯的原因是因為子進程并沒有正常退出呢。
5、官方的 stopAll() 實現(xiàn)原理也完全不是你示例代碼所寫的那樣的,大致原理是:
?(1) 父子進程均要安裝信號處理器
?(2) 父進程負責收集子進程并監(jiān)控起來等待子進程退出
?(3) 父進程會收到某種信號,之后將信號在發(fā)送給所有的子進程
?(4) 子進程收到信號后執(zhí)行相應的邏輯處理并退出
?(5) 父進程若在約定期限依然尚未退出,則SIGKILL強行干掉

  • back0893 2018-11-25

    1.這里就是我疑惑的,我使用posix_kill 在子進程中發(fā)送給父進程,父進程注冊的信號處理器,被我手動調(diào)用,應該執(zhí)行父進程的,但是父進程被阻塞直到子進程60s后退出才會觸發(fā)信號
    2.pcntl_async_signals(true) 來自動調(diào)用也是一樣的,會被阻塞
    3.父進程監(jiān)控子進程是否退出,子進程是一個死循環(huán),這里會父進程會被阻塞到所有的子進程退出,父進程收到了信號才會被執(zhí)行

  • back0893 2018-11-25

    應該就是這樣的,可能我理解不對,linux調(diào)用不明白,因為我看worker實現(xiàn)也是這樣的.其實我是fork你的網(wǎng)站上分享的那個demo

  • phpcreeper 2018-11-25

    @5032:
    1、我建議你把我列的那幾點再反復的看幾遍呢,深入理解。
    2、父進程并不是因子進程sleep了60后才觸發(fā)父進程的執(zhí)行,換句話,父進程阻塞是因為調(diào)用了wait 系統(tǒng)調(diào)用。
    3、子進程一開始執(zhí)行就立即發(fā)送了信號給父進程,父進程因dispatch也會隨即檢測到信號,上面說了并不是子進程休眠導致的,關鍵地方就在這里: 是因為一開始你設置的true參數(shù),這個會通知內(nèi)核立即重啟系統(tǒng)調(diào)用,從而再次發(fā)生阻塞,當你設置為false后,父進程立刻執(zhí)行,子進程或休眠或變?yōu)榻┦M程,除了strace看到真相外,這也是最好的證明了。

  • phpcreeper 2018-11-25

    @5032: 我網(wǎng)站的那段代碼本身沒有問題,那僅用作調(diào)試信號工作原理,我是根據(jù)你題示說的是 stopAll() 的實現(xiàn),那么那段demo代碼肯定是不能那么寫的。

  • back0893 2018-11-26

    @614:嗯嗯,我在自己磋磨下

  • back0893 2018-11-26

    @614:可以這樣理解不,雖然信號發(fā)送成功,如果內(nèi)核立即重啟系統(tǒng)調(diào)用那么主進程的信號處理人被阻塞?

  • phpcreeper 2018-11-26

    1、信號處理被阻塞? 這是什么概念哦,沒有這說法,這里的阻塞指的是進程阻塞,進程阻塞是因為進行了比如wait系統(tǒng)調(diào)用。
    2、內(nèi)核立即重啟系統(tǒng)調(diào)用必然會再次發(fā)生阻塞,除非再次檢測到新來信號,因為收到一次信號只會中斷一次系統(tǒng)調(diào)用。

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