成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

PHP多進(jìn)程系列筆記(一)

ddongjian0000 / 2004人閱讀

摘要:用于創(chuàng)建子進(jìn)程。該函數(shù)阻塞當(dāng)前進(jìn)程,只到當(dāng)前進(jìn)程的一個子進(jìn)程退出或者收到一個結(jié)束當(dāng)前進(jìn)程的信號。注意處需要注意子進(jìn)程需要防止子進(jìn)程也進(jìn)入循環(huán)。如果沒有,最終創(chuàng)建的子進(jìn)程不只個。

本系列文章將向大家講解pcntl_*系列函數(shù),從而更深入的理解進(jìn)程相關(guān)知識。

PCNTL在PHP中進(jìn)程控制支持默認(rèn)是關(guān)閉的。您需要使用 --enable-pcntl 配置選項(xiàng)重新編譯PHP的 CGI或CLI版本以打開進(jìn)程控制支持。

如果自帶的PHP沒有安裝pcntl擴(kuò)展,可以下載相同版本的源碼,進(jìn)入ext/pcntl使用phpize編譯安裝。

Note: 此擴(kuò)展在 Windows 平臺上不可用。
pcntl_fork
int pcntl_fork ( void )

用于創(chuàng)建子進(jìn)程。成功時,在父進(jìn)程執(zhí)行線程內(nèi)返回產(chǎn)生的子進(jìn)程的PID,在子進(jìn)程執(zhí)行線程內(nèi)返回0。失敗時,在父進(jìn)程上下文返回-1,不會創(chuàng)建子進(jìn)程,并且會引發(fā)一個PHP錯誤。

fork.php


命令行運(yùn)行:

$ php fork.php
Parent process,pid 98, child pid 99
Child process,pid 99

該例里父進(jìn)程還沒有來得及等子進(jìn)程運(yùn)行完畢就自動退出了,子進(jìn)程由 init進(jìn)程接管。通過 ps -ef | grep php 看到子進(jìn)程還在運(yùn)行:

[root@9355490fe5da /]# ps -ef | grep php
root       105     1  0 16:46 pts/0    00:00:00 php fork.php
root       107    27  0 16:46 pts/1    00:00:00 grep php

子進(jìn)程成為孤立進(jìn)程,ppid(父進(jìn)程id)變成1了。如果在父進(jìn)程里也加個sleep(5),你會看到子進(jìn)程ppid本來是大于1的,后來就變成1了。

注:如果是docker環(huán)境,孤立進(jìn)程的ppid可能是0。
pcntl_wait

pcntl_wait()函數(shù)用來讓父進(jìn)程等待子進(jìn)程退出,默認(rèn)情況下會阻塞主進(jìn)程。

阻塞模式

緊接著上面的例子,如果想等子進(jìn)程運(yùn)行結(jié)束后父進(jìn)程再退出,該怎么辦?那就用到pcntl_wait了。

int pcntl_wait ( int &$status [, int $options = 0 ] )

該函數(shù)阻塞當(dāng)前進(jìn)程,只到當(dāng)前進(jìn)程的一個子進(jìn)程退出或者收到一個結(jié)束當(dāng)前進(jìn)程的信號。

我們修改代碼:


此時再次運(yùn)行程序,父進(jìn)程就會一直等待子進(jìn)程運(yùn)行結(jié)束然后退出。

pcntl_waitpid()pcntl_wait()功能相同。前者第一個參數(shù)支持指定pid參數(shù),當(dāng)指定-1作為pid的值等同于后者。
int pcntl_waitpid ( int $pid , int &$status [, int $options = 0 ] )
當(dāng)已知子進(jìn)程pid的時候,可以使用pcntl_waitpid()。

這兩個函數(shù)返回退出的子進(jìn)程進(jìn)程號(>1),發(fā)生錯誤時返回-1,如果提供了 WNOHANG 作為option(wait3可用的系統(tǒng))并且沒有可用子進(jìn)程時返回0。

返回值為退出的子進(jìn)程進(jìn)程號時,想了解如何退出,可以通過 $status狀態(tài)碼反應(yīng)。

非阻塞模式

pcntl_wait()默認(rèn)情況下會阻塞主進(jìn)程,直到子進(jìn)程執(zhí)行完畢才繼續(xù)往下運(yùn)行。如果設(shè)置最后一個參數(shù)為常量WNOHANG,那么就不會阻塞主進(jìn)程,而是繼續(xù)執(zhí)行后續(xù)代碼, 此時 pcntl_waitpid 就會返回0。

示例:

 0){
            sleep(10);//此處為了方便看效果,實(shí)際不需要
            break;
        }
    } 
}else{
    $id = getmypid();   
    echo "Child process,pid {$id}
";   
    sleep(2); 
}

該示例里只有一個子進(jìn)程,看不出來非阻塞的好處,我們修改一下:

 $pid) {
        // $res = pcntl_wait($status, WNOHANG);
        $res = pcntl_waitpid($pid, $status, WNOHANG);//#3
        if ($res == -1 || $res > 0){
            echo time()." Child process exit,pid {$pid}
";   
            unset($child_pids[$key]);
        }else{
            // echo time()." Wait End,pid {$pid}
";   //#4
        }
    }
    
} 

#3處首先先去掉WNOHANG參數(shù),運(yùn)行:

$ php fork.1.php 
1528637334 Parent process,pid 6600, child pid 6601
1528637334 Child process,pid 6601,sleep 2
1528637334 Parent process,pid 6600, child pid 6602
1528637334 Child process,pid 6602,sleep 2
1528637334 Parent process,pid 6600, child pid 6603
1528637334 Child process,pid 6603,sleep 1
1528637336 Child process exit,pid 6601
1528637336 Child process exit,pid 6602
1528637336 Child process exit,pid 6603

我們看到,6603號進(jìn)程運(yùn)行時間最短,但是是最后回收。我們再加上WNOHANG參數(shù),運(yùn)行:

$ php fork.1.php 
1528637511 Parent process,pid 6695, child pid 6696
1528637511 Child process,pid 6696,sleep 2
1528637511 Parent process,pid 6695, child pid 6697
1528637511 Child process,pid 6697,sleep 1
1528637511 Parent process,pid 6695, child pid 6698
1528637511 Child process,pid 6698,sleep 3
1528637512 Child process exit,pid 6697
1528637513 Child process exit,pid 6696
1528637514 Child process exit,pid 6698

6697進(jìn)程最先回收!說明確實(shí)是異步非阻塞的。感興趣的朋友還可以開啟#4處代碼,未使用WNOHANG參數(shù)的時候,里面的代碼是不會運(yùn)行的。

注意:#2處需要注意子進(jìn)程需要exit,防止子進(jìn)程也進(jìn)入for循環(huán)。如果沒有exit(),最終創(chuàng)建的子進(jìn)程不只3個。

檢測status函數(shù)

pcntl_waitpcntl_waitpid兩個函數(shù)中的$status中存了子進(jìn)程的狀態(tài)信息,這個參數(shù)可以用于 pcntl_wifexitedpcntl_wifstopped、pcntl_wifsignaledpcntl_wexitstatus、 pcntl_wtermsigpcntl_wstopsig、pcntl_waitpid這些函數(shù)。

代碼片段:

while(1){
$res = pcntl_wait($status);
if ($res == -1 || $res > 0){

    if(!pcntl_wifexited($status)){
        //進(jìn)程非正常退出
        echo "service exit unusally; pid is $pid
";
    }else{
        //獲取進(jìn)程終端的退出狀態(tài)碼;
        $code = pcntl_wexitstatus($status);
        echo "service exit code: $code;pid is $pid 
";
    }

    if(pcntl_wifsignaled($status)){
        //不是通過接受信號中斷
        echo "service term not by signal;pid is $pid 
";
    }else{
        $signal = pcntl_wtermsig($status);
        echo "service term by signal $signal;pid is $pid
";
    }

    if(pcntl_wifstopped($status)){
        echo "service stop not unusally;pid is $pid 
";
    }else{
        $signal = pcntl_wstopsig($status);
        echo "service stop by signal $signal;pid is $pid
";
    }

    break;
}
參考

1、php多進(jìn)程 防止出現(xiàn)僵尸進(jìn)程
https://www.cnblogs.com/jkko1...
2、PCNTL函數(shù)族--PHP多進(jìn)程編程 (轉(zhuǎn))
https://www.cnblogs.com/zox20...


防盜版聲明:本文系原創(chuàng)文章,原發(fā)布于公眾號飛鴻影的博客(fhyblog)及博客園,轉(zhuǎn)載需作者同意。


歡迎關(guān)注公眾號及時獲取最新文章推送!


推薦!每月僅需$2.5,即可擁有配置SSD的VPS!

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/28874.html

相關(guān)文章

  • PHP進(jìn)程系列筆記(二)

    摘要:任何進(jìn)程在退出前使用退出都會變成僵尸進(jìn)程用于保存進(jìn)程的狀態(tài)等信息,然后由進(jìn)程接管。這時候就算手動結(jié)束腳本程序也無法關(guān)閉這個僵尸子進(jìn)程了。那么子進(jìn)程結(jié)束后,沒有回收,就產(chǎn)生僵尸進(jìn)程了。本小節(jié)我們通過安裝信號處理函數(shù)來解決僵尸進(jìn)程問題。 上一篇文章講解了pcntl_fork和pcntl_wait兩個函數(shù)的使用,本篇繼續(xù)講解PHP多進(jìn)程相關(guān)新知識。 僵尸(zombie)進(jìn)程 這里說下僵尸進(jìn)程...

    CatalpaFlat 評論0 收藏0
  • PHP進(jìn)程系列筆記(五)

    摘要:消息隊(duì)列更常見的用途是主進(jìn)程分配任務(wù),子進(jìn)程消費(fèi)執(zhí)行。子進(jìn)程前面加了個,這是為了防止父進(jìn)程還未往消息隊(duì)列中加入內(nèi)容直接退出。 前面幾節(jié)都是講解pcntl擴(kuò)展實(shí)現(xiàn)的多進(jìn)程程序。本節(jié)給大家介紹swoole擴(kuò)展的swoole_process模塊。 swoole多進(jìn)程 swoole_process 是swoole提供的進(jìn)程管理模塊,用來替代PHP的pcntl擴(kuò)展。 首先,確保安裝的swoole...

    qianfeng 評論0 收藏0
  • PHP進(jìn)程系列筆記(四)

    摘要:本節(jié)主要講解常用函數(shù)和進(jìn)程池的概念,也會涉及到守護(hù)進(jìn)程的知識。所以任何時候,建議預(yù)先創(chuàng)建好進(jìn)程,也就是使用進(jìn)程池的方式實(shí)現(xiàn)。 本節(jié)主要講解Posix常用函數(shù)和進(jìn)程池的概念,也會涉及到守護(hù)進(jìn)程的知識。本節(jié)難度較低。 Posix常用函數(shù) posix_kill 向指定pid進(jìn)程發(fā)送信號。成功時返回 TRUE , 或者在失敗時返回 FALSE 。 bool posix_kill ( int $...

    Cc_2011 評論0 收藏0
  • PHP 進(jìn)程系列筆記(三)

    摘要:本節(jié)講解幾個多進(jìn)程的實(shí)例。新開終端,我們使用命令查看進(jìn)程可以看到個進(jìn)程個主進(jìn)程,個子進(jìn)程。使用命令結(jié)束子進(jìn)程,主進(jìn)程會重新拉起一個新的子進(jìn)程。 本節(jié)講解幾個多進(jìn)程的實(shí)例。 多進(jìn)程實(shí)例 Master-Worker結(jié)構(gòu) 下面例子實(shí)現(xiàn)了簡單的多進(jìn)程管理: 支持設(shè)置最大子進(jìn)程數(shù) Master-Worker結(jié)構(gòu):Worker掛掉,Master進(jìn)程會重新創(chuàng)建一個

    focusj 評論0 收藏0
  • Swoole筆記

    摘要:修復(fù)添加超過萬個以上定時器時發(fā)生崩潰的問題增加模塊,下高性能序列化庫修復(fù)監(jiān)聽端口設(shè)置無效的問題等。線程來處理網(wǎng)絡(luò)事件輪詢,讀取數(shù)據(jù)。當(dāng)?shù)娜挝帐殖晒α艘院?,由這個線程將連接成功的消息告訴進(jìn)程,再由進(jìn)程轉(zhuǎn)交給進(jìn)程。此時進(jìn)程觸發(fā)事件。 本文示例代碼詳見:https://github.com/52fhy/swoo...。 簡介 Swoole是一個PHP擴(kuò)展,提供了PHP語言的異步多線程服務(wù)器...

    SHERlocked93 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<