PHP的pcntl進程控制教程一(pcntl_fork)

pcntl 簡介

PHP的進程控制支持實現了Unix方式的進程建立, 程序執行, 信號處理以及進程的中斷。 進程控制不能被應用在Web服務器環境,當其被用於Web服務環境時可能會帶來意外的結果。php

這份文檔用於闡述每一個進程控制函數的一般用法。關於Unix進程控制的更多信息建議您查閱 系統文檔中關於fork(2),waitpid(2),signal(2)等的部分或更全面的參考資料好比 《Unix環境高級編程》(做者:W. Richard Stevens,Addison-Wesley出版)。編程

PCNTL如今使用了ticks做爲信號處理的回調機制,ticks在速度上遠遠超過了以前的處理機制。 這個變化與「用戶ticks」遵循了相同的語義。您可使用declare() 語句在程序中指定容許發生回調的位置。這使得咱們對異步事件處理的開銷最小化。在編譯PHP時 啓用pcntl將始終承擔這種開銷,不論您的腳本中是否真正使用了pcntl。api

有一個調整是PHP 4.3.0以前的全部pcntl腳本要使其工做,要麼在指望容許回調的(代碼)部分使用 declare() ,要麼使用declare()新的全局語法 使其在整個腳本範圍有效。服務器

Note: 此擴展在 Windows 平臺上不可用。異步

官方文檔

pcntl官方文檔函數

pcntl_fork

# 來源官方

PHP 4 >= 4.1.0, PHP 5, PHP 7)

pcntl_fork — 在當前進程當前位置產生分支(子進程)。譯註:fork是建立了一個子進程,父進程和子進程 都從fork的位置開始向下繼續執行,不一樣的是父進程執行過程當中,獲得的fork返回值爲子進程 號,而子進程獲得的是0。

說明
int pcntl_fork ( void )
pcntl_fork()函數建立一個子進程,這個子進程僅PID(進程號) 和PPID(父進程號)與其父進程不一樣。fork怎樣在您的系統工做的詳細信息請查閱您的系統 的fork(2)手冊。

返回值
成功時,在父進程執行線程內返回產生的子進程的PID,在子進程執行線程內返回0。失敗時,在 父進程上下文返回-1,不會建立子進程,而且會引起一個PHP錯誤。

代碼

<?php
/**
 * Created by PhpStorm.
 * User: Object
 * Date: 2018/6/11
 * Time: 10:12
 */

const NEWLINE = "\n\n";

if (strtolower(php_sapi_name()) != 'cli') {
    die("請在cli模式下運行");
}

echo "當前進程:" . getmypid() . NEWLINE;

$pid = pcntl_fork(); //fork出子進程

//fork後父進程會走本身的邏輯,子進程從處開始走本身的邏輯,堆棧信息會徹底複製給子進程內存空間,父子進程相互獨立

if ($pid == -1) { // 建立錯誤,返回-1

    die('進程fork失敗');

} else if ($pid) { // $pid > 0, 若是fork成功,返回子進程id

    // 父進程邏輯
    $time = microtime(true);
    echo "我是父進程:{$time}".NEWLINE;

} else { // $pid = 0

    // 子進程邏輯
    $time = microtime(true);
    echo "我是子進程:{$time}".NEWLINE;
}

執行結果

當前進程:17472

我是父進程:1528697500.2961

我是子進程:1528697500.2961

fork後會子進程先執行仍是父進程先執行邏輯呢?

測試代碼

此處咱們調換上面代碼的父子進程的if順序
if ($pid == -1) { // 建立錯誤,返回-1

    die('進程fork失敗');

} else if (!$pid) { // $pid = 0

    // 子進程邏輯
    $time = microtime(true);
    echo "我是子進程:{$time}".NEWLINE;
} else if ($pid) { // $pid > 0, 若是fork成功,返回子進程id

    // 父進程邏輯
    $time = microtime(true);
    echo "我是父進程:{$time}".NEWLINE;

}

執行結果

當前進程:17472

我是父進程:1528697500.2961

我是子進程:1528697500.2961

測試總結

fork首先會執行父進程邏輯再執行子進程邏輯
相關文章
相關標籤/搜索