1. 程式人生 > >php裏進程創建和分析

php裏進程創建和分析

clas ret 父進程 存在 創建進程 AS printf 進行 class

pcntl_fork()函數創建一個子進程,這個子進程僅PID(進程號) 和PPID(父進程號)與其父進程不同
成功時,在父進程執行線程內返回產生的子進程的PID,在子進程執行線程內返回0。失敗時,在 父進程上下文返回-1,不會創建子進程

調用函數創建進程的時候,函數執行是有時間的,而新的進程剛好是在函數執行開始和結束之間創建出來的,
這樣,新的進程也執行了這個函數,所以函數也需要有返回值。
那麽對於該函數一次執行之後,父進程和子進程都會受到該函數的返回值
由於父進程創建了子進程,而子進程並沒有創建新的進程,所以子進程對於這個函數的返回結果是沒有的,
所以就給他賦了一個0
而父進程創建了子進程,子進程是存在pid的,所以就得到了那個進程的pid

下面不考慮進程創建失敗的情況

<?php
echo "###\n";
echo posix_getpid();
echo "\n------------\n";
$i=0;
while($i<2){
    $pid = pcntl_fork();
    echo "now pid:".sprintf("%5d",posix_getpid())."--->父pid:".sprintf("%5d",posix_getppid())."--->fork_return:".sprintf("%5d",$pid)."----->p_".$i++.PHP_EOL;
}
exit;

輸出和簡析

###
15280
------------
now pid:15280--->父pid:14413--->fork_return:15281----->p_0
now pid:15281--->父pid:15280--->fork_return:    0----->p_0
now pid:15280--->父pid:14413--->fork_return:15282----->p_1
now pid:15282--->父pid:15280--->fork_return:    0----->p_1
now pid
:15281--->父pid:15280--->fork_return:15283----->p_1 now pid:15283--->父pid:15281--->fork_return: 0----->p_1 發現打印了4次p_1 分析 當前pid 15280 i=0時記為step1 15280分裂成15280(pcntl_fork()返回15281) 15280分裂成15281(pcntl_fork()返回0) i=1時記為step2 step1的15280分裂成15280(pcntl_fork()返回15282) step1的15280分裂成15282(pcntl_fork()返回0) step1的15281分裂成15281(pcntl_fork()返回15283) step1的15281分裂成15283(pcntl_fork()返回0)

返回0的表示創建了新的子進程在子進程的返回
現在我們只要2個進程(更多也原理一樣)
如果使用循環
比如我們要5個進程

<?php
echo "###\n";
echo posix_getpid();
echo "\n------------\n";
$i=0;
while($i<5){
    $pid = pcntl_fork();
    echo "now pid:".sprintf("%5d",posix_getpid())."--->父pid:".sprintf("%5d",posix_getppid())."--->fork_return:".sprintf("%5d",$pid)."----->p_".$i++.PHP_EOL;
    //子進程裏的返回,不再進行while的pcntl_fork
    if($pid == 0){
        echo posix_getpid()." is a child procress!\n";
        return ‘‘;
    }
}
exit;
?>

輸出

###
15262
------------
now pid:15262--->父pid:14413--->fork_return:15263----->p_0
now pid:15263--->父pid:15262--->fork_return:    0----->p_0
15263 is a child procress!
now pid:15262--->父pid:14413--->fork_return:15264----->p_1
now pid:15264--->父pid:15262--->fork_return:    0----->p_1
15264 is a child procress!
now pid:15262--->父pid:14413--->fork_return:15265----->p_2
now pid:15265--->父pid:15262--->fork_return:    0----->p_2
15265 is a child procress!
now pid:15262--->父pid:14413--->fork_return:15266----->p_3
now pid:15262--->父pid:14413--->fork_return:15267----->p_4
now pid:15267--->父pid:15262--->fork_return:    0----->p_4
15267 is a child procress!
now pid:15266--->父pid:15262--->fork_return:    0----->p_3
15266 is a child procress!

這時由 15262產生了15263,15264,15265,15266,15267
可以看出所有子進程都在15262裏fork出的,是15262的直接子進程

php裏進程創建和分析