国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

ddongjian0000 / 2000人閱讀

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

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

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 平臺(tái)上不可用。
pcntl_fork
int pcntl_fork ( void )

用于創(chuàng)建子進(jìn)程。成功時(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ā)一個(gè)PHP錯(cuò)誤。

fork.php


命令行運(yùn)行:

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

該例里父進(jìn)程還沒有來得及等子進(jìn)程運(yùn)行完畢就自動(dòng)退出了,子進(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)程里也加個(gè)sleep(5),你會(huì)看到子進(jìn)程ppid本來是大于1的,后來就變成1了。

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

pcntl_wait()函數(shù)用來讓父進(jìn)程等待子進(jìn)程退出,默認(rèn)情況下會(huì)阻塞主進(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)程的一個(gè)子進(jìn)程退出或者收到一個(gè)結(jié)束當(dāng)前進(jìn)程的信號(hào)。

我們修改代碼:


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

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

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

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

非阻塞模式

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

示例:

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

該示例里只有一個(gè)子進(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號(hào)進(jìn)程運(yùn)行時(shí)間最短,但是是最后回收。我們?cè)偌由?b>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ù)的時(shí)候,里面的代碼是不會(huì)運(yùn)行的。

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

檢測(cè)status函數(shù)

pcntl_waitpcntl_waitpid兩個(gè)函數(shù)中的$status中存了子進(jìn)程的狀態(tài)信息,這個(gè)參數(shù)可以用于 pcntl_wifexitedpcntl_wifstoppedpcntl_wifsignaledpcntl_wexitstatuspcntl_wtermsigpcntl_wstopsigpcntl_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)){
        //不是通過接受信號(hào)中斷
        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ā)布于公眾號(hào)飛鴻影的博客(fhyblog)及博客園,轉(zhuǎn)載需作者同意。


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


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

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/28874.html

相關(guān)文章

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

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

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

    摘要:消息隊(duì)列更常見的用途是主進(jìn)程分配任務(wù),子進(jìn)程消費(fèi)執(zhí)行。子進(jìn)程前面加了個(gè),這是為了防止父進(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 評(píng)論0 收藏0
  • PHP進(jìn)程系列筆記(四)

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

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

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

    focusj 評(píng)論0 收藏0
  • Swoole筆記

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

    SHERlocked93 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<