php中pcntl_fork詳解


pcntl_fork()函數是php-pcntl模塊中用於創建進程的函數。(不支持windows)

至於php_pcntl擴展如何安裝開啟這里就不介紹了,只分析pcntl_fork()這個函數本身。

1.$one = 123;
2.$one++;
3.$two = time();
4.$pid = [];
5.$pid = pcntl_fork();
6.$three = time();

當:pcntl_fork()函數執行的時候,會創建一個子進程。子進程會復制當前進程,也就是父進程的所有:數據,代碼,還有狀態。

1.當pcntl_fork()創建子進程成功后,在父進程內,返回0,在子進程內返回自身的進程號,失敗則返回-1

2.子進程會復制父進程的代碼,數據。那么就說明:子,父進程擁有的代碼和數據會一模一樣。

3.重點:子進程會復制父進程的狀態,那么就有上面的示例代碼:在第五行執行了pcntl_fork,那么創建出的子進程,代碼也是從第五行開始執行的。又子進程復制了數據,代碼。所以,在子進程內同理存在:$one,$two等變量

for ($i = 0; $i < 3; $i++) {
    $pid = pcntl_fork();
}
sleep(30);

那么:上面的for循環,實際會產生多少個子進程?答案是7個,在linux下,用ps命令將可以看到8個進程(1個父進程,7個子進程)
原因:父進程在$i=0時,創建出一個子進程0,此時的子進程,還會繼續執行循環。創建出屬於自己的子進程。同理:$i=1時也會這樣……

參考: https://www.jianshu.com/p/5f383a85d663
 
PHP創建多進程的Demo示例:
<?php
/**
 * PHP多進程和多線程的處理
 */

//創建socket監聽
$socketserv = stream_socket_server('tcp://0.0.0.0:8000', $errno, $errstr);
//創建5個子進程
for ($i = 0; $i < 5; $i++) {
    //使用pcntl_fork()創建進程,會返回pid,如果pid==0,則表示主進程
    if (pcntl_fork() == 0) {
        //循環監聽
        while (true) {
            $conn = stream_socket_accept($socketserv);
            //如果監聽失敗,則重新去監聽
            if(!$conn){
                continue;
            }
            //讀取流信息,讀取的大小 是9000
            $request = fread($conn, 9000);
            //寫入響應
            $response = 'hello';
            fwrite($conn, $response);
            //關閉流
            fclose($conn);
        }
        //創建完所有的子進程,然后退出
        exit(0);
    }
}
運行  php stream_socket.php,使用 ps -ef 查看進程,會看到多出了如下的5個進程:

 

擴展:PHP的異步非阻塞模型 Reactor:

 

Reactor有4個核心的操作:
  • add 添加socket監聽到reactor
  • set 修改事件監聽,可以設置監聽的類型,如可讀、可寫
  • del 從reactor中移除,不再監聽事件
  • callback 就是事件發生后對應的處理邏輯,一般在add/set時制定。
         (C語言用函數指針實現,JS可以用匿名函數,PHP可以用匿名函數、對象方法數組、字符串函數名)
 
Reactor只是一個事件發生器,實際對socket句柄的操作,如 connect/accept、send/recv、close是在callback中完成的。
具體編碼可參考下面的代碼(需要先安裝Reactor擴展):
 
Reactor模型還可以與多進程、多線程結合起來用,既實現異步非阻塞IO,又利用到多核。
目前流行的異步服務器程序都是這樣的方式:如
  • Nginx:多進程Reactor
  • Nginx+Lua:多進程Reactor+協程
  • Golang:單線程Reactor+多線程協程
  • Swoole:多線程Reactor+多進程Worker 

參考:http://rango.swoole.com/archives/508


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM