zoukankan      html  css  js  c++  java
  • 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的逻辑退出,最终结束总进程
  • 相关阅读:
    php上传文件大小限制
    phpStudy for Linux (lnmp+lamp一键安装包)
    linux 常见问题
    Cmake设置环境变量
    NSIS Installer(被NSI脚本编译出来的target)获取命令行参数
    VS2010 Command Prompt Error:Cannot determine the location of the VS Common Tools folder
    关于老驱动不能在windows 8下正常安装的问题
    去除安装程序的窗口显示(类似于后台安装)
    NSIS操作系统环境变量
    NSIS检测操作系统x64还是x86的问题。
  • 原文地址:https://www.cnblogs.com/liliuguang/p/12617673.html
Copyright © 2011-2022 走看看