协程执行流程
最后更新于:2022-04-02 06:30:01
# 协程执行流程
[TOC]
协程执行流程遵循以下原则:
* 协程没有`IO`等待 正常执行PHP代码,不会产生执行流程切换
* 协程遇到`IO`等待 立即将控制权切,待`IO`完成后,重新将执行流切回原来协程切出的点
* 协程并行协程依次执行,同上一个逻辑
* 协程嵌套执行流程由外向内逐层进入,直到发生`IO`,然后切到外层协程,父协程不会等待子协程结束
## 无`IO`等待
* 正常执行`PHP`代码,不会产生执行流程切换
> 无`IO`操作的协程,相当于一次`PHP`函数调用
~~~
echo "main start\n";
go(function () {
echo "coro ".co::getcid()." start\n";
});
echo "end\n";
/*
main start
coro 1 start
end
*/
~~~
## `IO`等待
* 立即将控制权切,待`IO`完成后,重新将执行流切回原来协程切出的点
~~~
echo "main start\n";
go(function () {
echo "coro ".co::getcid()." start\n";
co::sleep(.1); //switch at this point
echo "coro ".co::getcid()." end\n";
});
echo "end\n";
/*
main start
coro 1 start
end
coro 1 end
*/
~~~
## 协程并行
协程依次执行,同上一个逻辑
~~~
echo "main start\n";
go(function () {
echo "coro ".co::getcid()." start\n";
co::sleep(.1);
echo "coro ".co::getcid()." end\n";
});
echo "main flag\n";
go(function () {
echo "coro ".co::getcid()." start\n";
co::sleep(.1);
echo "coro ".co::getcid()." end\n";
});
echo "end\n";
/*
main start
coro 1 start
main flag
coro 2 start
end
coro 1 end
coro 2 end
*/
~~~
## 协程嵌套
执行流程由外向内逐层进入,直到发生IO,然后切到外层协程,父协程不会等待子协程结束
~~~
echo "main start\n";
go(function () {
echo "coro ".co::getcid()." start\n";
go(function () {
echo "coro ".co::getcid()." start\n";
co::sleep(.1);
echo "coro ".co::getcid()." end\n";
});
echo "coro ".co::getcid()." do not wait children coroutine\n";
co::sleep(.2);
echo "coro ".co::getcid()." end\n";
});
echo "end\n";
/*
main start
coro 1 start
coro 2 start
coro 1 do not wait children coroutine
end
coro 2 end
coro 1 end
*/
~~~
~~~
echo "main start\n";
go(function () {
echo "coro ".co::getcid()." start\n";
go(function () {
echo "coro ".co::getcid()." start\n";
co::sleep(.2);
echo "coro ".co::getcid()." end\n";
});
echo "coro ".co::getcid()." do not wait children coroutine\n";
co::sleep(.1);
echo "coro ".co::getcid()." end\n";
});
echo "end\n";
/*
main start
coro 1 start
coro 2 start
coro 1 do not wait children coroutine
end
coro 1 end
coro 2 end
*/
~~~
';