• 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

  • 相关阅读:
    import 和 from … import 模块的变量、方法引用差异
    python引入模块的五种方式与内置模块
    webdriver定位元素的方法和基础函数的使用
    mysql update语句 in执行效率优化
    服务器配置jupyter notebook
    安装CUDA和cuDNN
    Linux命令后台运行
    Ubuntu查看系统信息(CPU、GPU信息)
    Linux下scp用法简析
    如何解决“This app is damaged and can’t be opened. You should move it to the Trash”
  • 原文地址:https://www.cnblogs.com/rxbook/p/10763359.html
Copyright © 2020-2023  润新知