协程执行流程

协程执行流程遵循以下原则:

  • 协程没有IO等待 正常执行PHP代码,不会产生执行流程切换
  • 协程遇到IO等待 立即将控制权切,待IO完成后,重新将执行流切回原来协程切出的点
  • 协程并行协程依次执行,同上一个逻辑
  • 协程嵌套执行流程由外向内逐层进入,直到发生IO,然后切到外层协程,父协程不会等待子协程结束

IO等待

  • 正常执行PHP代码,不会产生执行流程切换

IO操作的协程,相当于一次PHP函数调用

  1. echo "main start\n";
  2. go(function () {
  3. echo "coro ".co::getcid()." start\n";
  4. });
  5. echo "end\n";
  6. /*
  7. main start
  8. coro 1 start
  9. end
  10. */

IO等待

  • 立即将控制权切,待IO完成后,重新将执行流切回原来协程切出的点
  1. echo "main start\n";
  2. go(function () {
  3. echo "coro ".co::getcid()." start\n";
  4. co::sleep(.1); //switch at this point
  5. echo "coro ".co::getcid()." end\n";
  6. });
  7. echo "end\n";
  8. /*
  9. main start
  10. coro 1 start
  11. end
  12. coro 1 end
  13. */

协程并行

协程依次执行,同上一个逻辑

  1. echo "main start\n";
  2. go(function () {
  3. echo "coro ".co::getcid()." start\n";
  4. co::sleep(.1);
  5. echo "coro ".co::getcid()." end\n";
  6. });
  7. echo "main flag\n";
  8. go(function () {
  9. echo "coro ".co::getcid()." start\n";
  10. co::sleep(.1);
  11. echo "coro ".co::getcid()." end\n";
  12. });
  13. echo "end\n";
  14. /*
  15. main start
  16. coro 1 start
  17. main flag
  18. coro 2 start
  19. end
  20. coro 1 end
  21. coro 2 end
  22. */

协程嵌套

执行流程由外向内逐层进入,直到发生IO,然后切到外层协程,父协程不会等待子协程结束

  1. echo "main start\n";
  2. go(function () {
  3. echo "coro ".co::getcid()." start\n";
  4. go(function () {
  5. echo "coro ".co::getcid()." start\n";
  6. co::sleep(.1);
  7. echo "coro ".co::getcid()." end\n";
  8. });
  9. echo "coro ".co::getcid()." do not wait children coroutine\n";
  10. co::sleep(.2);
  11. echo "coro ".co::getcid()." end\n";
  12. });
  13. echo "end\n";
  14. /*
  15. main start
  16. coro 1 start
  17. coro 2 start
  18. coro 1 do not wait children coroutine
  19. end
  20. coro 2 end
  21. coro 1 end
  22. */
  1. echo "main start\n";
  2. go(function () {
  3. echo "coro ".co::getcid()." start\n";
  4. go(function () {
  5. echo "coro ".co::getcid()." start\n";
  6. co::sleep(.2);
  7. echo "coro ".co::getcid()." end\n";
  8. });
  9. echo "coro ".co::getcid()." do not wait children coroutine\n";
  10. co::sleep(.1);
  11. echo "coro ".co::getcid()." end\n";
  12. });
  13. echo "end\n";
  14. /*
  15. main start
  16. coro 1 start
  17. coro 2 start
  18. coro 1 do not wait children coroutine
  19. end
  20. coro 1 end
  21. coro 2 end
  22. */