CSP 编程模型
CSP ,全称:Communicating Sequential Process ,翻译成中文是,通信顺序进程,最初于Tony Hoare的1977年的论文中被描述,影响了许多编程语言的设计。用于描述两个的ulinix并发的实体通过共享的通讯管道(channel)进行通信的 并发模型。在该模型中,channel 是比较重要的对象,它并不关注发送消息的实体,而只关心与发送消息时实体使用的channel
其简单的模型可以大概简化如下:
work1 ——->Channel ————->work2
work1和work2并不直接通信,而是通过中间的媒介角色Channel
进行通信。消息的发送者work1和work2通过channel
实现了松耦合。、
Go语言中是通过goruntime 和channel实现的;
php swoole 中是通过协程(\Swoole\Coroutine)+ 通道(Channel)来实现的
下面是使用php 的swoole 写的协程并发:
$http = new swoole_http_server("127.0.0.1", 9501); $http->on("request", function ($request, $response) { $client = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP); $client->connect("127.0.0.1", 8888, 0.5); //调用connect将触发协程切换 $client->send("hello world from swoole"); //调用recv将触发协程切换 $ret = $client->recv(); $response->header("Content-Type", "text/plain"); $response->end($ret); $client->close(); }); $http->start();
当代码执行到connect()
和recv()
函数时,底层会触发进行协程切换,此时可以去处理其他的事件或者接受新的请求。当此客户端连接成功或者后端服务回包后,底层会恢复协程上下文,代码逻辑继续从切换点开始恢复执行。开发者整个过程不需要关心整个切换过程。
协程可以理解为纯用户态的线程
,其通过协作而不是抢占来进行切换
。相对于进程或者线程,协程所有的操作都可以在用户态完成
,创建和切换的消耗更低。Swoole可以为每一个请求创建对应的协程,根据IO的状态来合理的调度协程,这会带来了以下优势:
开发者可以无感知的用同步的代码编写方式
达到异步IO的效果和性能,避免了传统异步回调所带来的离散的代码逻辑和陷入多层回调中导致代码无法维护
同时由于底层封装了协程,所以对比传统的PHP层协程框架,开发者不需要使用yield关键词来标识一个协程IO操作,所以不再需要对yield的语义进行深入理解以及对每一级的调用都修改为yield,这极大的提高了开发效率
可以满足大部分开发者的需求。对于私有协议,开发者可以使用协程的TCP或者UDP接口去方便的封装。
swoft 框架中,在bin文档的开头部分,就指定了协程的set option:nums
代码如下:
Swoole\Coroutine::set([ 'max_coroutine' => 300000, ]);
参考文档:
1.php swoole的协程
2.并发模型:Actors与CSP
3.Actor模型和CSP模型的区别
4.Actor模