协程的睡眠问题co::sleep

刚碰到一个坑,分享一下,看看有没有人有解答,估计是个bug 描述: 在HttpServer的onRequest中执行完CO::sleep(0.01); 再执行file_get_contents请求一个延时比较长的Http请求,然后再执行CO::sleep(0.01); 这个时候CO::sleep(0.01)执行的时间将不再准确,而是变得和file_get_contents所请求的http页面一样的延时

测试代码:

<?php
$serv = new Swoole\Http\Server("0.0.0.0", 9503);

$serv->on('Request', function($request, $response) {
    echo date('YmdHis')." 第一次睡眠\n";
    CO::sleep(0.01);
    echo date('YmdHis')." 第一次睡眠 结束\n";

    echo date('YmdHis')." 调用一个耗时5s的http请求\n";
    file_get_contents('http://www.92lan.com/sleep.php');
    echo date('YmdHis')." 调用一个耗时5s的http请求  完成\n";

    echo date('YmdHis')." 第二次睡眠\n";
    CO::sleep(1);    /** 这里应该只会睡眠1s,但实际上睡眠了5s,和上一个file_get_contents的耗时一样长 */
    echo date('YmdHis')." 第二次睡眠 结束\n";

    $response->end("<h1>Hello Swoole!</h1>");
});

$serv->start();

执行结果: 第一部分为时间信息

20180419204232 第一次睡眠
20180419204232 第一次睡眠 结束
20180419204232 调用一个耗时5s的http请求
20180419204237 调用一个耗时5s的http请求  完成
20180419204237 第二次睡眠
20180419204243 第二次睡眠 结束
2018-04-19 20:47
0
0

yyjie

赞同来自:

在每次CO::sleep之后,加入一行 swoole_timer_after(1, function(){}); 能修正这个问题。。

近期无时间撸底层代码,业务代码就先这么处理着了,有感兴趣的大牛么?

2018-04-23 11:02
0

twosee

赞同来自:

因为阻塞操作会让异步server退化为同步server, 也就是阻塞整个进程

2018-04-25 17:04
0

yyjie

赞同来自:

@twosee 不是你这个原因,是file_get_content的阻塞执行,在执行完成之后,会影响到后面的co::sleep的睡眠时长,本来应该睡眠1s,但实际睡眠了上一次file_get_content阻塞的时间。

2018-04-25 18:03
0

twosee

赞同来自:

@yyjie 我说的和你说的是一码事啊..

2018-06-20 23:08

要回复问题请先登录注册