原本的代码,do中用到的modbus tcp链接(一种底层3次tcp握手才能在上面跑的协议)。其中foreach下面会每一次迭代会同步执行代码,包括建立modbus tcp链接(因为不同的服务端ip)。
我想问的是,这里面用协程会不会提升并发?
$plcs = [];
foreach ($devicePlcs as $devicePlc) {
$plcs[] = $this->do($devicePlc); // 实际业务代码;
}
协程版本:(因为子协程间是一遇到网络io就理论上让给主协程去控制)
$plcs = [];
foreach ($devicePlcs as $devicePlc) {
Coroutine::create(function () {
$plcs[] = $this->do($devicePlc); // 实际业务代码;
}
}
不知道我的理解正确不?
没有找到
得看底层具体用什么函数连接的modbus tcp链接,如果这个函数swoole有hook到就行
用的是aldas/modbus-tcp-client这个库,不知道能否加速?
我看了下用的是stream系列的函数,swoole是有hook这些函数的,不过,tcp连接必须在协程内部创建,不能在协程外部创建,否则还是阻塞的
也就是说,在Coroutine::create(function () {
里面创建。才能生效?
还有个问题?就是说一个协程内,底层只建立一个tcp的3次握手,然后就进行多次的modbus 交互,也就是复用了tcp链接,这种情况下,用协程还能加速吗?
我的意思是,协程是不是仅在tcp链接和断开的情况下,就是发生网络io的情况下,才会产生切换协程的操作,否则不产生协程切换
第一个问题,是的。
第二个问题,是的,只要用了IO,就发生协程切换
Coroutine::create(function () {
$con = conection::build(); // 假设已经3次握手成功
$modbusReceive1 = $con->connnect('''AA'); //假设发起AA寄存器的请求,发生io,并阻止协程运行下一个bb的请求
$modbusReceive2 = $con->connnect('bb');// 假设发起bb寄存器的请求
}
这种情况下,单个协程如何加速呢? 这个AA的请求明显会阻塞住bb啊?
或者说,我不要协程包裹,直接写,也是一样的啊?
建议你还是先了解线程,进程,协程的概念吧,协程的作用是产生io是时不阻塞当前进程,但是阻塞操作依旧是阻塞的.
你这个例子不用协程直接用AynscTcpConnection更好
IO切换肯定是多协程下面收益是最大的,单协程其实就跟单进程差不多了。协程有自己的上下文,你把两个连接放在一起肯定是顺序的,连接B要等连接A连接好了才行
感觉,如果用Async会怎样?在一个foreach循环内,每次循环的时候,都用async去请求tcp,?
循环内使用asynchronous tcp和循环内创建多个协程没太大区别,看你熟悉哪个
我晕,,我废好大功夫才弄懂协程。。他们应该有些啥区别才是的吧,,。。
为啥发明协程呢?
天大的打击,,,我花好长时间才弄懂的协程。。
协程理论上还有很大的优势吧,比如说遇到了磁盘io?不单单是网络io才会切换协程。
你上面的例子只有网络io,所以都差不多,如果有磁盘io,那就用协程
谢谢!