使阻塞调用异步

phi*_*294 2 crystal-lang

我正在为 X11 使用 Crystal 绑定,典型用法如下所示

loop do
    event = display.next_event # <- blocking!
    # do stuff with event
end
Run Code Online (Sandbox Code Playgroud)

这工作正常,但我现在无法并行执行任何操作,因为它next_event是本机 C 代码,因此永远不会产生结果。

xlib 的 NextEvent 总是阻塞的,在 C 中也是如此。有一个关于它的线程提供了可能的替代方案,但轮询比 更慢并且对 CPU 的要求更高next_event,所以我想坚持使用阻塞调用。我是否必须将其放入单独的操作系统线程中?-Dpreview_mt实际上解决了这个问题,但这是一个实验性标志,并使所有并发线程化,这是不必要的(编辑:刚刚发现,这不是真的,有spawn same_thread: true do语法)。我有什么选择?

编辑:我刚刚发现此主题中对此进行了更详细的讨论,值得阅读该主题。如果您能以某种方式获得 FD,也可以解决此FileDescriptor问题。wait_readable

Joh*_*ler 5

当 lib 函数阻塞时,您无法在 Crystal 中对其执行任何操作。您需要在单独的操作系统线程中运行它,以便能够并行运行其他代码。这就是此类方法的设计用途。

在 Crystal 中,您不需要preview_mt只运行单独的操作系统线程。该标志启用 Crystal 运行时的多线程调度。对于您的用例,您实际上只需要一个专用线程来等待阻塞调用完成。线程 API 未公开,但您可以使用它Thread.new { }来创建新的操作系统线程并在该线程中运行 proc。

我认为我们需要为该语言添加一个用于此类用例的公共 API。但目前,它还没有记录在案(因此它可能会发生变化,但这不太可能)。