EASYLT文档 > Swoole框架 > 多进程/协程

多进程

  • 仅支持在server目录下服务文件中创建,有两种创建模式,分别为单独进程模式与进程池模式:单独进程模式的进程间通信支持QUEUE消息队列;进程池模式的进程间通信支持PIPE管道。
  •    进程模式通过$process>create()中的第二个参数切换,'single'为单独进程模式,'pool'为进程池模式。
  • 单独进程模式
    <?php
    //引入服务器配置文件【必须实现】
    include('server.ini');
    //实例化进程【必须实现】
    $process = new Process;//单独进程模式下创建多进程运行为异步非阻塞模式,可在每个进程中创建服务器,进程间用QUEUE消息队列通信。
    
    //创建进程【必须实现】
    $process->create(function($process){//创建第一个进程
        //$process为进程对象
        //匿名回调函数中写你的业务
        $process->push(mt_rand(1,9));//写入数据到QUEUE消息队列
    },'single'); //'single'为单独进程模式,'pool'为进程池模式。
    
    $process->create(function($process){//创建第二个进程
        $read = $process->pop();//读取消息队列中的数据,多进程消息队列为争抢模式,无法将消息投递给指定进程,但消息是共享的,可一次性读取出来。
        echo $read;
    },'single');
    
    
    进程池模式
  •    pool进程池模式下请勿在进程中创建如TCP等服务器,进程池模式适用于处理有状态消费业务,如从消息队列中读取消息并消费。
             需要在进程容器中创建如TCP等服务器请选择single单独进程模式。
  • <?php
    //引入服务器配置文件【必须实现】
    include('server.ini');
    
    //实例化进程【必须实现】
    $process = new Process;//进程池模式运行为异步非阻塞模式,进程间用PIPE管道通信。
    
    //创建进程池【必须实现】
    $process->create(function($process){
        //$process为进程对象
        //匿名回调函数中写你的业务
        //如需写入数据到PIPE管道请return $var
    },'pool');
    
    //读取PIPE管道中的数据【可选项】
    $process->pipe(function($response_data){
        //匿名回调函数中写你的业务
        //$response_data为读取PIPE管道中的数据
    });
    
    

    协程

  • 仅支持在server目录下服务文件中创建
  •    通过new Async()创建协程容器,将协程放置到容器的匿名回调函数中自动实现异步。
  •    在new Async()协程容器中创建协程才可自动实现异步,但协程容器不可在服务器中创建,如TCP服务器,会发生冲突导致运行错
       误。
  •    未创建协程容器时,在配置文件config_swoole.php中配置常量ASYNC_CO开启异步协程同样使协程自动实现异步。
  •    异步Mysql、异步Redis基于协程开发,用法同理;通过异步Mysql、异步Redis读取的数据需要进行发送时,请先判断该数据是否
       存在,因为是异步非阻塞运行,后续代码优先执行,可能第一次会发送空数据。
  • <?php
    include('server.ini');
    new Async(function($channel){//$channel为协程通信通道变量
        Async::co(function()use($channel){//创建协程一,同一协程内为同步阻塞执行
            //协程通信的消费者应小于等于生产者,否则会发生异常,且消费按顺序读取数据;
            $channel->push('发送数据到管道');//先use闭包引入$channel变量,push发送数据到通道;
            sleep(10);
            echo '这是协程一';
        });
        Async::co(function()use($channel){//创建协程二
            $channel->pop();//先use闭包引入$channel变量,pop从通道读取数据;
            echo '这是协程二';
        });
    });
    //以上运行协程一执行要等待10秒,则协程一挂起执行协程二,先后输出:这是协程二  这是协程一