× 警告!旧版文档已经暂停维护,请查看新版文档。点击前往新版文档

Coroutine::resume

恢复某个协程,使其继续运行。

function Swoole\Coroutine::resume(int $coroutineId);
  • 参数$coroutineId为要恢复的协程ID,在协程内可以使用Coroutine::getUid获取到协程的ID
  • 当前协程处于挂起状态时,另外的协程中可以使用resume再次唤醒当前协程

实例

use Swoole\Coroutine as co;
$id = go(function(){
    $id = co::getUid();
    echo "start coro $id\n";
    co::suspend();
    echo "resume coro $id @1\n";
    co::suspend();
    echo "resume coro $id @2\n";
});
echo "start to resume $id @1\n";
co::resume($id);
echo "start to resume $id @2\n";
co::resume($id);
echo "main\n";

--EXPECT--
start coro 1
start to resume 1 @1
resume coro 1 @1
start to resume 1 @2
resume coro 1 @2
main

  • 落落

    这段代码有问题吧。Swoole\Coroutine::create 返回值是布尔类型的,$id = go(/* callback */) 并不能返回新建协程的 ID,反而会被强制转换成数字 1。

    另外让我有点困惑的是,在 4.0.4 版本的 Swoole 里,我把这段代码放在 Swoole\Http\Server::onRequest 里,onRequest 本身已经在 ID 为 2 的协程里了,而新生成的协程 ID 为 3。然后手动调整一下,执行如下代码:

            $id = go(function(){
                $id = co::getUid();
                echo "start coro $id\n";
                co::suspend($id);
                echo "resume coro $id @1\n";
                co::suspend($id);
                echo "resume coro $id @2\n";
            });
    
            $id = 3;
    
            echo "start to resume $id @1\n";
            co::resume($id);
            echo "start to resume $id @2\n";
            co::resume($id);
            echo "main\n";
    

    显示为

    start coro 3
    start to resume 3 @1
    start to resume 3 @2
    PHP Warning:  Swoole\Coroutine::resume(): Nothing can coroResume. in /var/www/html/swoole/http_server.php on line 95
    main
    resume coro 3 @1
    

    看不明白。

  • 落落

    第一次 co::resume($id); 貌似成功了(没报错),但却没马上恢复协程并显示 resume coro 3 @1。 第二次 co::resume($id); 提示不能恢复,原因还是第一次恢复协程的时机延后了。 执行顺序和 Demo 期望的不一样。

  • 落落

    上面的 Demo 应该是 Swoole2 上的,$id 确实为 1(true 转换而来),在 Swoole4 里,onRequest 回调也是一个协程,所以新建协程 ID 不为 1。在 Swoole4 里这样写可以强行达到 Demo 期望的值:

            go(function () {
                $id = Co::getUid();
                echo "start coro {$id}\n";
                Co::suspend($id);
                echo "resume coro {$id} @1\n";
                Co::suspend($id);
                echo "resume coro {$id} @2\n";
            });
    
            $id = 3;// 4.1.0 及以上版本可以使用 `Co::listCoroutines()` 方法,但依然没有直接获取新创建协程的 ID 的办法
    
            echo "start to resume {$id} @1\n";
            Co::resume($id);
            Co::sleep(1);
            echo "start to resume {$id} @2\n";
            Co::resume($id);
            Co::sleep(1);
            echo "main\n";
    

  • ifelse

    你确定 $id = 3; 这样赋值协程ID是正确的吗

  • ifelse

    swoole在OnWorkerStart、OnConnect、OnRequest时分别创建了协程

  • 蔺某人

    1楼的,2楼说的对,从新了解下协程的概念