Swoole协程执行流程

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

  • 协程没有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
*/

 

评论