php使用thinkphp快速搭建swoole玩转协程

swoole4开始支持了类似go的协程,以下是进程、线程、协程之间的联系。

1,进程
经典定义:一个执行中程序的实例。系统中的每个程序都运行在某个进程的上下文中。(-摘自 CSAPP)

进程是系统资源分配的最小单位

2,线程(thread)
线程就是运行在进程上下文中的逻辑流。

线程是操作系统能够进行运算调度的最小单位。

3,协程
相对 子例程而言,协程更为一般和灵活,但在实践中使用没有子例程那样广泛。

根据维基百科对子例程的描述:是一个大型程序中的某部分代码,由一个或多个语句块组成。它负责完成某项特定任务,而且相较于其他代码,具备相对的独立性。我可以将子例程理解为一个函数。
 

协程与线程的区别:


1 一个线程可以多个协程,一个进程也可以单独拥有多个协程。

扫描二维码关注公众号,回复: 14364646 查看本文章

2 线程进程都是同步机制,而协程则是异步。

3 协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态。

4线程是抢占式,而协程是非抢占式的,所以需要用户自己释放使用权来切换到其他协程,因此同一时间其实只有一个协程拥有运行权,相当于单线程的能力。

5协程并不是取代线程, 而且抽象于线程之上, 线程是被分割的CPU资源, 协程是组织好的代码流程, 协程需要线程来承载运行, 线程是协程的资源, 但协程不会直接使用线程, 协程直接利用的是执行器(Interceptor), 执行器可以关联任意线程或线程池, 可以使当前线程, UI线程, 或新建新程.。

6 线程是协程的资源。协程通过Interceptor来间接使用线程这个资源。

7 极高的执行效率:因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显;

8 不需要多线程的锁机制:因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。
 

废话有点密了哈哈,本文将采用宝塔+thinkphp6+swoole搭建。具体流程如下:

首先让我们来看看thinkphp6的手册,据说是支持了swoole扩展快速搭建。

链接:Swoole · ThinkPHP6.0完全开发手册 · 看云

说真的,文档写的太对付了,不像workerman那样直接简单。

这里我打算用另一种方式快速搭建。

thinkphp支持自定义指令,链接:自定义指令 · ThinkPHP6.0完全开发手册 · 看云

根据这个创建一个swoolews指令,如下:

1、安装宝塔(可略过):

宝塔面板下载,免费全能的服务器运维软件

2、安装thinkphp6(可略过):

安装 · ThinkPHP6.0完全开发手册 · 看云

3、创建自定义指令:

 

 

'swoolews' => 'app\command\Swoolews',

 

 4、直接去swoole官方文档(抄代码!哈哈!):

Swoole4 文档

 

<?php
declare (strict_types = 1);

namespace app\command;

use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;

class Swoolews extends Command
{
    protected function configure()
    {
        // 指令配置
        $this->setName('swoolews')
            ->setDescription('the swoolews command');
    }

    protected function execute(Input $input, Output $output)
    {
        // 指令输出
        $output->writeln('swoolews');

        //创建WebSocket Server对象,监听0.0.0.0:9502端口
        $ws = new \Swoole\WebSocket\Server('0.0.0.0', 9501);

        //监听WebSocket连接打开事件
        $ws->on('Open', function ($ws, $request) {
            $ws->push($request->fd, "hello, welcome\n");
        });

        //监听WebSocket消息事件
        $ws->on('Message', function ($ws, $frame) {
            echo "Message: {$frame->data}\n";
            $ws->push($frame->fd, "server: {$frame->data}");
        });

        //监听WebSocket连接关闭事件
        $ws->on('Close', function ($ws, $fd) {
            echo "client-{$fd} is closed\n";
        });

        $ws->start();


    }
}

 5、在项目目录下启动ws服务并测试(注意!记得服务器和宝塔开启9501端口,咱们服务配置的是9501端口):

 测试ws网站链接:在线websocket测试-online tool-postjson

 随便发送个消息:

 

 有回应就说明没有问题喽,当然上述代码可能不易于维护,你也可以根据swoole官方文档给的基础知识改写一下:

Swoole4 文档

6、测试协程

协程文档链接:Swoole4 文档

 

 

<?php
declare (strict_types = 1);

namespace app\command;

use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use Swoole\Coroutine;
use function Swoole\Coroutine\go;
class Swoolews extends Command
{
    protected function configure()
    {
        // 指令配置
        $this->setName('swoolews')
            ->setDescription('the swoolews command');
    }

    protected function execute(Input $input, Output $output)
    {
        // 指令输出
        $output->writeln('swoolews');

        //创建WebSocket Server对象,监听0.0.0.0:9502端口
        $ws = new \Swoole\WebSocket\Server('0.0.0.0', 9501);

        //监听WebSocket连接打开事件
        $ws->on('Open', function ($ws, $request) {
            $ws->push($request->fd, "hello, welcome\n");
        });

        //监听WebSocket消息事件
        $ws->on('Message', function ($ws, $frame) {
            echo "Message: {$frame->data}\n";
            //协程测试
            for($i=0;$i<10;$i++) {
                go(function () use ($ws ,$frame, $i) {

                    for ($n = 100; $n--;) {
                        usleep(1000);
                    }
                });
            }
            $ws->push($frame->fd, "server: 完成");
        });

        //监听WebSocket连接关闭事件
        $ws->on('Close', function ($ws, $fd) {
            echo "client-{$fd} is closed\n";
        });

        $ws->start();


    }
}

 重启服务

 

 效果还是不错的!

7、swoole协程与go协程的区别

go语言协程相对智能很多,使用的是MPG模式调度协程~ 简单说就是产生的所有协程其它的线程是有空就能去执行的,是多cpu调度的,相当于有一个协程池,空闲的cpu会去池子里执行协程任务,相比swoole的单cpu调用更有效地利用系统资源。可以方便的实现API的并行处理,达到处理效率的最大化。 

所以咱们也不去夸大swoole的能力,真正要说协程比较强大的还是goroutine,这个咱不犟。

swoole协程还是在io操作上能提高效率,其他情况还是考虑php多进程,java多线程或go的goroutine吧!

记得三连哦!

海蜘蛛:只要自己足够废物,那么就没有天敌!

猜你喜欢

转载自blog.csdn.net/weixin_47723549/article/details/124661158