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

Coroutine

版本更新

4.4.4版本中系统操作相关的协程APICoroutine类中,迁移到了Coroutine\System类中。独立为一个新模块。为了向下兼容,底层依然保留了在Coroutine类之上的别名方法。

  • Coroutine::sleep对应Coroutine\System::sleep
  • Coroutine::fgets对应Coroutine\System::fgets

短名称

2.0.132.1.0或更高版本中,增加了协程短名特性,简化了协程相关API的名称书写。可修改php.ini设置swoole.use_shortname来关闭/开启短名,默认为开启。

创建协程

go(function () {
    co::sleep(0.5);
    echo "hello";
});
go("test");
go([$object, "method"]);

通道操作

$c = new chan(1);
$c->push($data);
$c->pop();

协程客户端

$redis = new Co\Redis;
$mysql = new Co\MySQL;
$http = new Co\Http\Client;
$tcp = new Co\Client;
$http2 = new Co\Http2\Client;

系统操作

System::sleep(100);
System::fread($fp);
System::gethostbyname('www.baidu.com');

延迟执行

defer(function () use ($db) {
    $db->close();
});

  • lyy

    每个进程下的协程处理器是一个还是多个?? 同一进程下多个协程是时唤醒是否会并行执行?是否会有资源竞争?

  • zhao

    同一时间只能处理一个协程代码,不是多线程。 协程不会并行执行,是协同执行,比如 任务1 ,任务2 ,执行任务1时,里面有让出代码co::sleep(0.5); 就会暂时退出,这样任务2 先可以处理。任务2 处理完毕,就会恢复到任务1中断处,继续处理。 不存多进程,多线程。 个人理解。

  • 13262732358

    Coroutine 和task 还有go 区别是什么 应用场景是什么

  • 18521323182

    我for 4000个元素分别生成了对应处理的4000个协程,这里涉及与某服务器的通讯,但由于一下子太多请求上去了对方拒绝了一部分请求,我希望每500个协程为一组,等待这500个协程工作完毕后再注册下一个,逻辑代码代码是这样的: for ...{ go(...) if(!($i / 400)){ //swoole_event::wait(); \Swoole\Event::wait(); } }

    但并不能如愿,请问正确的实现方式是怎样的呢?

  • 18521323182

    我for 4000个元素分别生成了对应处理的4000个协程,这里涉及与某服务器的通讯,但由于一下子太多请求上去了对方拒绝了一部分请求,我希望每500个协程为一组,等待这500个协程工作完毕后再注册下一个,逻辑代码代码是这样的:

    for ...{
       go(...)
        if(!($i / 400)){
            //swoole_event::wait();
            \Swoole\Event::wait();
        }
    }
    

    但并不能如愿,请问正确的实现方式是怎样的呢?

  • 15270657047

    没有异步io就没有必要使用协程是吧?

  • 18656999023

    @zhao 有见解

  • 18701502107

    应该是多个异步io的操作在一起时 有必要使用,假设是一个io的场景感觉可以不使用