ruby 中 windows 台机器的 fork 等效项

Equivalent of fork do for windows machines in ruby

我有一个 ruby 脚本,它在后台将一些代码分叉到 运行 并退出命令行。

代码:

fork do
  #Example background code
  x = 0

  while x < 100 do
     File.write("./example_file.txt", x.to_s, Mode: "a")
  end
end

我想在 windows 系统上使用相同的脚本 运行,而不需要额外的 gems/libraries。我看过 spawn() 但无法满足我的需要。

fork 和 Windows 并不是很合得来。 Unix 和 Windows 中的进程哲学非常不同。

在 Unix 中,进程是功能分解的主要机制。 IE。在 Unix 中,应用程序或服务将由多个协作进程组成的管道组成。进程在 Unix 中的使用方式与对象在 Ruby 中的使用方式类似。为了让它工作,进程是廉价轻量级

在Windows中,组件是功能分解的主要机制。 IE。在 Windows 中,应用程序或服务将由 单个 进程组成,使用多个组件实现。 组件 的使用方式类似于 Ruby 中的对象或 Unix 中的进程。这意味着 Windows 中的进程不需要廉价或轻量级,事实上,它们非常昂贵、笨重,并且创建和销毁的速度很慢。

除了使用的流程非常不同且成本更高之外,它们 的交互方式也非常不同。用于创建、管理和销毁进程的 API 非常不同。没有与 Windows 中的 fork 完全等价的东西,也没有简单、高效的方法来实现它。

不幸的是,去 TruffleRuby 或 JRuby 也无济于事:而 TruffleRuby 和 JRuby Windows 支持传统上往往比 YARV 更好,这 not 适用于 fork 因为 JVM 不允许它:forking 在 JVM 上创建一个分支其中只有主线程,但是 none 的 GC、编译器、I/O 或其他帮助程序和辅助线程,这让您的 JVM 损坏。它只有在你立即exec一个不同的进程,从而退出 JVM 时才真正起作用。

也就是说,Kernel#fork特殊 用法可以可能 在 JRuby 上实现,因为(如果我没记错的话),您可以在同一个 JVM 中实例化多个 JRuby 实例。因此,对于这种特定的用法,您只在后台执行一些 Ruby 代码,您实际上 不需要 fork,您可以启动一个不同线程中的新 JRuby 实例。

但据我所知,这并没有实现。 (虽然第一次贡献可能会成为一个有趣的项目!)

最接近于您在 Windows 中使用 Kernel#spawn 的代码可能是这样的:

spawn(RbConfig.ruby, '-e' << <<~BLOCK_END)
  #Example background code
  x = 0

  while x < 100 do
     File.write("./example_file.txt", x.to_s, Mode: "a")
  end
BLOCK_END

但这不是解决问题的正确方法。您正在将此视为 X/Y 问题:您遇到了 X 问题。你知道在 Unix 中 的解决方案是 Y。现在,你问的问题不是“我如何解决 问题 X Windows”,而是问“如何解决”我在Windows”上实施解决方案Y”,甚至不问Y是否是解.

因此,您的问题不应该是 Windows 中 fork 的等效项,而是如何设计 Windows 中的应用程序。