PHP多進(jìn)程pcntl_fork屯换、pcntl_wait那些事

PHP在多線程支持方面一直被人詬病编丘,其實(shí)PHP可以支持多線程,不過需要單獨(dú)安裝擴(kuò)展模塊彤悔;
另外相比于多線程嘉抓,其實(shí)多進(jìn)程模塊使用方面比多線程要更友好一些,如果你想在PHP中體驗(yàn)多進(jìn)程OR多線程晕窑,那就跟隨村長開始吧抑片!

PHP多進(jìn)程

一般涉及兩個(gè)函數(shù), pcntl_fork, pcntl_wait

pcntl_fork

用于創(chuàng)建子進(jìn)程杨赤,會(huì)在在當(dāng)前進(jìn)程當(dāng)前位置產(chǎn)生分叉(所以取名fork)敞斋;

這個(gè)子進(jìn)程僅 PID(進(jìn)程號(hào)) 和 PPID(父進(jìn)程號(hào))與其父進(jìn)程不同;子進(jìn)程的PID為0疾牲,PPID 為當(dāng)前腳本執(zhí)行時(shí)的進(jìn)程號(hào)植捎。
成功創(chuàng)建時(shí),在父進(jìn)程執(zhí)行線程內(nèi)返回產(chǎn)生的子進(jìn)程的 PID说敏,在子進(jìn)程執(zhí)行線程內(nèi)返回 0鸥跟。
失敗時(shí),在 父進(jìn)程上下文返回 -1盔沫,不會(huì)創(chuàng)建子進(jìn)程医咨,并且會(huì)引發(fā) PHP 錯(cuò)誤。

pcntl_wait

等待或返回 fork 的子進(jìn)程狀態(tài), 注:該方法會(huì)阻塞當(dāng)前進(jìn)程的執(zhí)行架诞;

執(zhí)行該函數(shù)時(shí)拟淮,會(huì)掛起當(dāng)前進(jìn)程的執(zhí)行,直到一個(gè)子進(jìn)程退出或接收到一個(gè)信號(hào)要求中斷當(dāng)前進(jìn)程或調(diào)用一個(gè)信號(hào)處理函數(shù)谴忧;
如果一個(gè)子進(jìn)程在調(diào)用此函數(shù)時(shí)已退出(俗稱僵尸進(jìn)程)很泊,此函數(shù)會(huì)立刻返回角虫,子進(jìn)程使用的所有系統(tǒng)資源將被釋放;

執(zhí)行順序:

  • 1.程序執(zhí)行時(shí)委造,從外到內(nèi)創(chuàng)建fork戳鹅,再從內(nèi)層最后一次fork開始依次退出;
  • 2.如一次fork之后昏兆,其父進(jìn)程因 pcntl_wait 阻塞枫虏,會(huì)等待之前已被執(zhí)行的【任意fork子進(jìn)程】退出后,再執(zhí)行后面的邏輯爬虱;
  • 3.執(zhí)行本子進(jìn)程的父進(jìn)程依次循環(huán)步驟【2】的邏輯直到退出隶债,最終結(jié)束總進(jìn)程;

參考示例:

$maxLoop = 11; // 最大允許的folk次數(shù)跑筝,超過此數(shù)量后直接退出
$idxStart = 0; // folk次數(shù)-計(jì)數(shù)器
$maxcnt = 3; // 最大可允許的同時(shí)創(chuàng)建的進(jìn)程數(shù)死讹,可理解為 進(jìn)程并發(fā)量;
$cnt = 0; // 已創(chuàng)建的進(jìn)程 計(jì)數(shù)器曲梗;
while (1) { 
    $pid = pcntl_fork();
    if($pid===-1){
        die('folk err...');
    } else if($pid) {
        $idxStart++; // folk次數(shù)-計(jì)數(shù)器
        $cnt++;
        // 控制最大并發(fā)執(zhí)行進(jìn)程數(shù)赞警,超過此數(shù)量,等待 任一子進(jìn)程退出 后再執(zhí)行稀并;
        if($cnt >= $maxcnt){
            // pcntl_wait 里的 status 參數(shù)是引用傳遞仅颇,PHP 會(huì)存儲(chǔ)狀態(tài)信息到 status 參數(shù)上,通過 status 參數(shù)可監(jiān)測(cè)當(dāng)前進(jìn)程是否正常執(zhí)行完退出等等碘举,這里不作詳細(xì)解釋忘瓦,感興趣的可直接參考PHP官網(wǎng);
            pcntl_wait($status); // 防止僵尸子進(jìn)程
            echo PHP_EOL, "Iam waiting: $cnt", PHP_EOL;
            print_r([$idxStart, $status]);
            echo PHP_EOL;
            if($idxStart>$maxLoop) {
                // 超過最大允許的folk次數(shù)引颈,退出耕皮!
                echo PHP_EOL, "loop-num: {$idxStart}, stop...", PHP_EOL;
                exit(0);
            }
            $cnt--;
        }
    } else {
        sleep(1);
        echo PHP_EOL, "curr-i: $cnt", PHP_EOL;
        exit(0); // 避免子進(jìn)程中執(zhí)行foreach循環(huán)
        // 或者使用下面的方法,直接-kill
        posix_kill(getmypid(),9); // Instead of calling exit(), we use posix_kill()
    }
}
第二種調(diào)用方式
function mainExec()
{
    $count = 6;
    for ($i = 1; $i <= $count; $i++) {
        $pid = pcntl_fork();
        if ($pid > 0) {
            // 主進(jìn)程相關(guān)操作...
        } else if (0 == $pid) {
            task($i);
            exit; // 一定要退出蝙场,否則子進(jìn)程會(huì)繼承上下文繼續(xù)執(zhí)行
        } else {
            echo "fork失敗" . PHP_EOL;
        }
    }

    // sleep(10); // 放開此方法凌停,會(huì)出現(xiàn)僵尸進(jìn)程

    while ($count) {
        // 注意,pcntl_wait 是可以脫離循環(huán)主體獨(dú)立執(zhí)行的售滤;
        $pid = pcntl_wait($result);
        var_dump($pid);
        var_dump($result);
        $count--;
    }
}

function task($taskId)
{
    // 此處罚拟,多進(jìn)程執(zhí)行相關(guān)邏輯。完箩。赐俗。
    echo "task {$taskId} was done..", PHP_EOL;
}
mainExec();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市弊知,隨后出現(xiàn)的幾起案子阻逮,更是在濱河造成了極大的恐慌,老刑警劉巖秩彤,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叔扼,死亡現(xiàn)場(chǎng)離奇詭異事哭,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)瓜富,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門鳍咱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人食呻,你說我怎么就攤上這事流炕。” “怎么了仅胞?”我有些...
    開封第一講書人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長剑辫。 經(jīng)常有香客問我干旧,道長,這世上最難降的妖魔是什么妹蔽? 我笑而不...
    開封第一講書人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任椎眯,我火速辦了婚禮,結(jié)果婚禮上胳岂,老公的妹妹穿的比我還像新娘编整。我一直安慰自己,他們只是感情好乳丰,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開白布掌测。 她就那樣靜靜地躺著,像睡著了一般产园。 火紅的嫁衣襯著肌膚如雪汞斧。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,394評(píng)論 1 310
  • 那天什燕,我揣著相機(jī)與錄音粘勒,去河邊找鬼。 笑死屎即,一個(gè)胖子當(dāng)著我的面吹牛庙睡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播技俐,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼乘陪,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了虽另?” 一聲冷哼從身側(cè)響起暂刘,我...
    開封第一講書人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎捂刺,沒想到半個(gè)月后谣拣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體募寨,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年森缠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拔鹰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡贵涵,死狀恐怖列肢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情宾茂,我是刑警寧澤瓷马,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站跨晴,受9級(jí)特大地震影響欧聘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜端盆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一怀骤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧焕妙,春花似錦蒋伦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至寺旺,卻和暖如春爷抓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背阻塑。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來泰國打工蓝撇, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人陈莽。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓渤昌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親走搁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子独柑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 實(shí)際上PHP是有多線程的忌栅,只是很多人不常用。使用PHP的多線程首先需要下載安裝一個(gè)線程安全版本(ZTS版本)的PH...
    白紅薯粉閱讀 501評(píng)論 0 0
  • 多進(jìn)程--fork 場(chǎng)景:日常任務(wù)中曲稼,有時(shí)需要通過php腳本執(zhí)行一些日志分析索绪,隊(duì)列處理等任務(wù)湖员,當(dāng)數(shù)據(jù)量比較大時(shí),可...
    金星show閱讀 1,113評(píng)論 0 2
  • PHP多進(jìn)程實(shí)例:本地并發(fā)只能通過語言自己的特性在程序本身實(shí)現(xiàn)多任務(wù)效果瑞驱,一般來說現(xiàn)在的語言會(huì)通過多線程或多進(jìn)程的...
    手扶拖拉機(jī)_6e4d閱讀 771評(píng)論 0 0
  • 阿里云服務(wù)器3折開售(點(diǎn)此直達(dá)) 可是PHP這個(gè)渣渣娘摔,在apache或者nginx中容器內(nèi)根本用不了多進(jìn)程或者多線...
    IronMan999閱讀 251評(píng)論 1 0
  • 前提 安裝php_pcntl擴(kuò)展 主要函數(shù) pcntl_fork()函數(shù)執(zhí)行的時(shí)候,會(huì)創(chuàng)建一個(gè)子進(jìn)程唤反。子進(jìn)程會(huì)復(fù)制...
    E狼閱讀 520評(píng)論 0 0