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 中的应用程序。
我有一个 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 中的应用程序。