【问题标题】:How does asynchronous Ruby work in Vim?异步 Ruby 在 Vim 中是如何工作的?
【发布时间】:2012-12-22 11:12:42
【问题描述】:

如果你用 +ruby 编译最新版本的 Vim,你可以在 Vim 中使用 :ruby 命令。

当我运行一些异步 Ruby 代码时,“幕后”发生了什么?

例如:

:ruby <<EOS
print 'hello'
Thread.new do
  sleep 1
  print 'world'
end
EOS
# hello

:ruby print 'foo'
# world
# foo

这会立即打印出 'hello',正如预期的那样。但是,在我运行另一个 :ruby 命令之前,'world' 不会打印。 Vim 是否只支持一个线程,并将新线程推送到某种队列中以便在下一个 :ruby 命令上运行?

我已经尝试在src/if_ruby.c 中查看 Vim 的源代码,但我的 Ruby C-Extension 阅读技巧并不是最好的。

我在问,因为我想编写一些 Ruby,每隔几秒轮询一次并更新一个 Vim 窗口。

【问题讨论】:

  • 是的,Vim 是单线程的。有一些异步库(this onethis one,可能还有其他......)您可能会觉得有趣。

标签: ruby vim embedded-ruby


【解决方案1】:

Vim 本身是单线程的。但也有一些例外或解决方法:

  1. Python 线程正在工作,但由于某种原因不在 ARM 上。虽然我不能说如果你从非主线程运行vim.* 方法会发生什么。我看到它在一些插件中使用,但在线程中没有vim.*
  2. Python 多处理模块运行良好(尽管您需要禁用所有 vim 信号处理程序)。我个人在我的 aurum 插件中使用了这个解决方案。我猜 ruby​​ 等价物会起作用,但 AFAIR 它只是一个 fork() 调用,使用简单的字节管道作为唯一的通信,没有像 multiprocessing.Pipe (传递一组有限的 python 对象的管道)、multiprocessing.Queue (包装器)那么复杂围绕实现对象队列的管道),multiprocessing.Value(使用对象接口存储固定大小的值的共享内存)或multiprocessing.Lock(不知道它是什么,但名称本身就说明了目的)。至少不在标准库或核心中。

AFAIK 一些较旧的 ruby​​ 版本使用绿色线程,因此(从操作系统的角度来看)是单线程的,而较新的 ruby​​ 现在使用 POSIX 线程。您可以尝试更新,也许这会起作用。虽然你最好选择其他的东西作为测试(比如在单独的线程中修改一些变量),而不是调用 vim 的东西。您可以在用户系统上找到的任何当前 python 版本都使用 POSIX 线程,这可能是 ruby​​ 线程不起作用而 python 线程起作用的根本原因。

【讨论】:

    猜你喜欢
    • 2017-02-08
    • 1970-01-01
    • 2011-05-02
    • 2012-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-12
    相关资源
    最近更新 更多