相当于 ruby 中 windows 机器的 fork do
Posted
技术标签:
【中文标题】相当于 ruby 中 windows 机器的 fork do【英文标题】:Equivalent of fork do for windows machines in ruby 【发布时间】:2022-01-21 07:34:21 【问题描述】:我有一个 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/库。我查看了 spawn() 但无法满足我的需求。
【问题讨论】:
您介意添加 Windows 上发生的错误吗? 为什么精确的错误信息很重要?fork
在 Windows 上不存在,错误消息中的确切文字告诉您它不存在,不要更改它不存在的事实。
@PedroPaiva fork() function is unimplemented on this machine
【参考方案1】:
fork
和 Windows 不能很好地结合在一起。 Unix 和 Windows 中处理进程的理念非常不同。
在 Unix 中,进程是功能分解的主要机制。 IE。在 Unix 中,应用程序或服务将由多个协作进程组成的管道组成。进程在 Unix 中的使用方式与对象在 Ruby 中的使用方式相似。为了使其发挥作用,流程便宜且轻量级。
在 Windows 中,组件是功能分解的主要机制。 IE。在 Windows 中,应用程序或服务将由一个单个进程组成,使用多个组件实现。 组件 的使用类似于 Ruby 中的对象或 Unix 中的进程。这意味着 Windows 中的进程不需要廉价或轻量级,事实上,它们非常昂贵、沉重且创建和销毁速度慢。
除了使用非常不同且成本更高的流程之外,它们的交互方式也非常不同。用于创建、管理和销毁进程的 API 非常不同。在 Windows 中没有与 fork
完全等效的方法,也没有简单、高效的方法来实现它。
不幸的是,使用 TruffleRuby 或 JRuby 也无济于事:虽然 TruffleRuby 和 JRuby 的 Windows 支持传统上往往比 YARV 更好,但这不适用于fork
,因为 JVM 支持不允许:JVM 上的forking
创建了一个分支,其中只有主线程,但没有 GC、编译器、I/O 或其他帮助程序和辅助线程,这会让你的 JVM 崩溃。只有当您立即 exec
一个不同的进程,它才真正起作用,从而退出 JVM。
话虽如此,Kernel#fork
的这种特殊用法可能可以在 JRuby 上实现,因为(如果我没记错的话),您可以在相同的JVM。因此,对于这种特殊用途,您只在后台执行一些 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。现在,不是问“我如何在 Windows 上解决 problem X”这个问题,而是问“我如何实施解决方案” Y on Windows”,甚至没有质疑 Y 是否是正确的解决方案。
所以,您的问题不应该是 Windows 中的 fork
等价物是什么,而是如何在 Windows 中设计应用程序。
【讨论】:
以上是关于相当于 ruby 中 windows 机器的 fork do的主要内容,如果未能解决你的问题,请参考以下文章
Windows 上的 ExecJS::RuntimeError 试图遵循 rubytutorial
Windows 中的 Jenkins 和 Ruby On Rails 4
Windows 上未初始化的常量 Sprockets::SassCacheStore 错误(学习 ruby on rails 书)