PHP的pcntl進程控制之pcntl_wait


這篇文章主要介紹了關於PHP的pcntl進程控制之pcntl_wait,有着一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

 

pcntl_wait 簡介

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

# 來源官方

 

pcntl_wait — 等待或返回fork的子進程狀態

 

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

 

wait函數刮起當前進程的執行直到一個子進程退出或接收到一個信號要求中斷當前進程或調用一個信號處理函數。 如果一個子進程在調用此函數時已經退出(俗稱僵屍進程),此函數立刻返回。子進程使用的所有系統資源將 被釋放。關於wait在您系統上工作的詳細規范請查看您系統的wait(2)手冊。

 

Note:

這個函數等同於以-1作為參數pid 的值並且沒有options參數來調用pcntl_waitpid() 函數。

 

參數

status

pcntl_wait()將會存儲狀態信息到status 參數上,這個通過status參數返回的狀態信息可以用以下函數 pcntl_wifexited(), pcntl_wifstopped(), pcntl_wifsignaled(), pcntl_wexitstatus(), pcntl_wtermsig()以及 pcntl_wstopsig()獲取其具體的值。

 

options

如果您的操作系統(多數BSD類系統)允許使用wait3,您可以提供可選的options 參數。如果這個參數沒有提供,wait將會被用作系統調用。如果wait3不可用,提供參數 options不會有任何效果。options的值可以是0 或者以下兩個常量或兩個常量“或運算”結果(即兩個常量代表意義都有效)。

 

options可用值

WNOHANG    如果沒有子進程退出立刻返回。

WUNTRACED    子進程已經退出並且其狀態未報告時返回。

返回值

pcntl_wait()返回退出的子進程進程號,發生錯誤時返回-1,如果提供了 WNOHANG作為option(wait3可用的系統)並且沒有可用子進程時返回0。

測試代碼

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

<?php

/**

 * Created by PhpStorm.

 * User: Object

 * Date: 2018/6/11

 * Time: 10:28

 */

if (strtolower(php_sapi_name()) != 'cli') {

    die("請在cli模式下運行");

}

 

$index = 0;

$loop = 1;

while ($index < $loop) {

 

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

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

 

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

 

        die('進程fork失敗');

 

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

 

        // 父進程邏輯

 

        pcntl_wait($status); // 父進程必須等待一個子進程退出后,再創建下一個子進程。

 

        $child_id = $pid; //子進程的ID

        $pid = posix_getpid(); //獲取當前進程Id

        $ppid = posix_getppid(); // 進程的父級ID

        $time = microtime(true);

        echo "我是父進程,fork的子進程id: {$child_id};當前進程id:{$pid};父進程id:{$ppid}; 當前index:{$index}; 當前時間:{$time}".PHP_EOL;

 

    } else { // $pid = 0

 

        // 子進程邏輯

        $cid = $pid;

        $pid = posix_getpid();

        $ppid = posix_getppid();

        $myid = getmypid();

        $time = microtime(true);

        echo "我是子進程,當前進程id:{$pid};父進程id:{$ppid}; 當前index:{$index}; 當前時間:{$time}".PHP_EOL;

        //exit;

        //sleep(2);

    }

    $index++;

}

loop = 1 執行結果

1

2

3

4

5

當前進程:16604

 

我是子進程,當前進程id:16605;父進程id:16604; 當前index:0; 當前時間:1528696774.1978

 

我是父進程,fork的子進程id: 16605;當前進程id:16604;父進程id:15128; 當前index:0; 當前時間:1528696774.2032

loop = 2 執行結果

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

當前進程:16613

 

我是子進程,當前進程id:16614;父進程id:16613; 當前index:0; 當前時間:1528696781.4751

 

當前進程:16614

 

我是子進程,當前進程id:16615;父進程id:16614; 當前index:1; 當前時間:1528696781.4756

 

我是父進程,fork的子進程id: 16615;當前進程id:16614;父進程id:16613; 當前index:1; 當前時間:1528696781.4802

 

我是父進程,fork的子進程id: 16614;當前進程id:16613;父進程id:15128; 當前index:0; 當前時間:1528696781.4858

 

當前進程:16613

 

我是子進程,當前進程id:16616;父進程id:16613; 當前index:1; 當前時間:1528696781.4863

 

我是父進程,fork的子進程id: 16616;當前進程id:16613;父進程id:15128; 當前index:1; 當前時間:1528696781.4913

loop = 3 執行結果

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

當前進程:16625

 

我是子進程,當前進程id:16626;父進程id:16625; 當前index:0; 當前時間:1528696787.3334

 

當前進程:16626

 

我是子進程,當前進程id:16627;父進程id:16626; 當前index:1; 當前時間:1528696787.3338

 

當前進程:16627

 

我是子進程,當前進程id:16628;父進程id:16627; 當前index:2; 當前時間:1528696787.3345

 

我是父進程,fork的子進程id: 16628;當前進程id:16627;父進程id:16626; 當前index:2; 當前時間:1528696787.3391

 

我是父進程,fork的子進程id: 16627;當前進程id:16626;父進程id:16625; 當前index:1; 當前時間:1528696787.3434

 

當前進程:16626

 

我是子進程,當前進程id:16629;父進程id:16626; 當前index:2; 當前時間:1528696787.3441

 

我是父進程,fork的子進程id: 16629;當前進程id:16626;父進程id:16625; 當前index:2; 當前時間:1528696787.3496

 

我是父進程,fork的子進程id: 16626;當前進程id:16625;父進程id:15128; 當前index:0; 當前時間:1528696787.3543

 

當前進程:16625

 

我是子進程,當前進程id:16630;父進程id:16625; 當前index:1; 當前時間:1528696787.3548

 

當前進程:16630

 

我是子進程,當前進程id:16631;父進程id:16630; 當前index:2; 當前時間:1528696787.3555

 

我是父進程,fork的子進程id: 16631;當前進程id:16630;父進程id:16625; 當前index:2; 當前時間:1528696787.3599

 

我是父進程,fork的子進程id: 16630;當前進程id:16625;父進程id:15128; 當前index:1; 當前時間:1528696787.3643

 

當前進程:16625

 

我是子進程,當前進程id:16632;父進程id:16625; 當前index:2; 當前時間:1528696787.3649

 

我是父進程,fork的子進程id: 16632;當前進程id:16625;父進程id:15128; 當前index:2; 當前時間:1528696787.3697

總結

1.從執行的多次結果得知,程序從外到內創建fork。然后再從內最后一次fork開始退出
2.如一次fork之后,程序的父進程因pcntl_wait阻塞,然后等待本次fork的子進程退出,然后相應的子進程的父進程執行邏輯並退出
3.然后執行本子進程的父進程依次循環2的邏輯退出,最終結束總進程


免責聲明!

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



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