php使用thinkphp快速搭建swoole玩转协程
2023-03-29 23:03:03
145
{{single.collect_count}}

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

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

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

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

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

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

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

协程与线程的区别:


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

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 文档

 

 

<?phpdeclare (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 文档

 

 

 

<?phpdeclare (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吧!

记得三连哦!

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

回帖
全部回帖({{commentCount}})
{{item.user.nickname}} {{item.user.group_title}} {{item.friend_time}}
{{item.content}}
{{item.comment_content_show ? '取消' : '回复'}} 删除
回帖
{{reply.user.nickname}} {{reply.user.group_title}} {{reply.friend_time}}
{{reply.content}}
{{reply.comment_content_show ? '取消' : '回复'}} 删除
回帖
收起
没有更多啦~
{{commentLoading ? '加载中...' : '查看更多评论'}}