【问题标题】:Is the order of execution of resolved Awaitables well-defined in Hack?Hack 中已解决的 Awaitables 的执行顺序是否明确定义?
【发布时间】:2017-01-11 01:00:29
【问题描述】:

下面的例子触发了 1000 个间隔为 100μs 的异步 usleep 调用,然后在 joining 之前阻塞了主线程:

<?hh
$awaitable = HH\Asio\v((new Vector(range(1, 1000)))->map((int $wait_time) ==> {
    return async {
        await HH\Asio\usleep($wait_time*100);
        echo $wait_time."\n";
    };
}));
usleep(1000000);
HH\Asio\join($awaitable);

The result in stdout (3v4l) 表示控制返回到async 范围的顺序。

该程序始终输出一个从 1000 到 1 的单调递减序列,这表明完成的 Awaitables 被压入堆栈并在线程以 LIFO 顺序释放后弹出。这个订单是真的吗,我可以信赖吗?

【问题讨论】:

    标签: async-await hacklang


    【解决方案1】:

    这是故意不指定的,并且将来可能会更改 - 并且之前已经更改过。您唯一可以依赖的异步函数是,在您 await 它们之后,它们就会执行并返回它们的结果。

    (这也意味着,例如,您不应依赖调用异步函数时发生的情况,但不要立即对其进行await。)

    【讨论】:

      【解决方案2】:

      如果您依赖 Awaitables 被收集或执行的确切顺序,您可能做错了什么。

      Awaitables 应该用于 IO。

      您能否再解释一下为什么需要精确排序?

      【讨论】:

      • 本来我以为可以在 Observer 实现中使用一致性排序来进行合并操作(其实我是希望 FIFO 的),但是昨天进一步思考之后,单独的一致性排序还不够强大。
      【解决方案3】:

      是的,这个排序 * 是真实的,就像ready await handles are explicitly processed in LIFO order。然而,正如@pablo-alcubilla 所写,在它进入 HHVM 规范之前不应该依赖它。

      【讨论】:

      • 出于性能原因,它在代码中,但语言规范对此只字未提。
      • 不要依赖这个 - 它是故意不指定的,并且之前可以(并且已经!)改变了。
      猜你喜欢
      • 2014-02-07
      • 2011-10-30
      • 1970-01-01
      • 2011-11-27
      • 1970-01-01
      • 2017-06-06
      • 1970-01-01
      • 1970-01-01
      • 2017-05-15
      相关资源
      最近更新 更多