zoukankan      html  css  js  c++  java
  • Swoole的多进程模块

    介绍

    Swoole是有自己的一个进程管理模块,用来替代PHP的pcntl扩展,需要注意Process进程在系统是非常昂贵的资源,创建进程消耗很大,另外创建的进程过多会导致进程切换开销大幅上升

    僵尸进程和孤儿进程的区别

      1. 僵尸进程:一个子进程在父进程还没有调用wait()方法或者waitpid()方法的情况下退出,这个子进程就是僵尸进程;

      2. 孤儿进程:一个父进程退出,它的一个或多个子进程还在运行,子进程将成为孤儿进程,孤儿进程将被init进程所收养;

      3. 僵尸进程将会导致资源浪费,而孤儿进程则不会。

    一、定义
    什么是僵尸进程
    维基百科的定义:在类UNIX系统中,僵尸进程是指完成执行(通过exit系统调用,或运行时发生致命错误或收到终止信号所致)但在操作系统的进程表中仍然有一个表项(进程控制块PCB),处于”终止状态”的进程。

    这个定义很准确,但并不好理解,通俗的说法是一个进程fork了一个子进程,子进程先于父进程退出,但父进程没有调用wait(通过wait系统调用读取退出进程的退出态,退出进程的在进程表中的表项就被删除),导致这个进程已经退出但是仍在进程表中占有一个位置,这种进程称为僵尸进程。

    什么是孤儿进程
    孤儿进程:一个进程fork了一个子进程, 父进程先于子进程退出,运行中的子进程称为孤儿进程。
    孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

    下面,让我们来看2个示例:僵尸进程

    echo 'ppid = ' . getmypid(), PHP_EOL;
     $process = new swoole_process(function (swoole_process $worker) {
        echo 'pid = ' . getmypid(), PHP_EOL;
        sleep(10);
        echo 'child process exit', PHP_EOL;
    }, false);
     
    $process->start();
     
    sleep(1000);
    echo 'parent process exit', PHP_EOL;
    #子进程在父进程没有执行完就退出了,所以会产生僵尸进程
    #一般流程是子进程在父进程执行完wait后再退出,

     孤儿进程

    echo 'ppid = ' . getmypid(), PHP_EOL;
    $process = new swoole_process(function (swoole_process $worker) {
        echo 'pid = ' . getmypid(), PHP_EOL;
        sleep(1000);
        echo 'child process exit', PHP_EOL;
    }, false);
    $process->start();
    sleep(10);
    echo 'parent process exit', PHP_EOL;

    为什么不使用pcntl

    1. pcntl没有提供进程间通信的功能
    2. pcntl不支持重定向标准输入和输出
    3. pcntl只提供了fork这样原始的接口,容易使用错误

    Swoole是怎么解决的

      1. swoole_process提供了基于unixsock的进程间通信,使用很简单只需调用write/read或者push/pop即可
      2. swoole_process支持重定向标准输入和输出,在子进程内echo不会打印屏幕,而是写入管道,读键盘输入可以重定向为管道读取数据
      3. swoole_process提供了exec接口,创建的进程可以执行其他程序,与原PHP父进程之间可以方便的通

    创建进程

    SwooleProcess::__construct(callable $function, $redirect_stdin_stdout = false, $create_pipe = true)

      $function,子进程创建成功后要执行的函数,底层会自动将函数保存到对象的callback属性上。如果希望更改执行的函数,可赋值新的函数到对象的callback属性

      $redirect_stdin_stdout,重定向子进程的标准输入和输出。启用此选项后,在子进程内输出内容将不是打印屏幕,而是写入到主进程管道。读取键盘输入将变为从管道中读取数据。默认为阻塞读取。

      $create_pipe,是否创建管道,启用$redirect_stdin_stdout后,此选项将忽略用户参数,强制为true。如果子进程内没有进程间通信,可以设置为 false。

    <?php
    for ($i = 0; $i < 6; $i++) {#创建了3个子进程
        $process = new SwooleProcess(function ($process) {
            echo PHP_EOL . posix_getpid() . PHP_EOL;
        }, false, false);
        $process->start();
    }
    swoole_process::wait();//等待防止出现僵尸进程
    ?>

     

  • 相关阅读:
    SQLite的总结与在C#的使用
    Linq中比较字符串类型的日期
    C#中委托,匿名函数,lamda表达式复习
    MYSQL中SUM (IF())
    C#在属性中用Lambda语法
    Mysql绿色版安装和遇到的问题
    FormsAuthentication权限管理
    存储过程中高性能安全式SQL拼接
    JavaScript实现搜索联想功能
    JavaScript组成
  • 原文地址:https://www.cnblogs.com/zh718594493/p/12251630.html
Copyright © 2011-2022 走看看