我的开发环境是运行红宝石1.9.3p125(RubyInstaller)和轨道3.2.8在Windows机器。
,来了一次又一次,使用第三方的宝石时,是缺乏fork()的Windows上的一个问题。 这已经阻碍了最近我使用几乎任何分布式测试运行的宝石(如能力这些 ),由于他们对叉的依赖。
在计算器上一些老的问题,试图找到解决这个同样的问题,但要么加入Process.spawn到红宝石之前,还是来自人们被迫使用Ruby的旧版本,某些其他原因。
其中提出的解决方案是使用Cygwin获得fork()的支持,这简直是出了这个问题 - 我想我宁愿完全切换到Linux,在这之前。
另一个提出的解决方案已经使用Win32的过程宝石获得fork()的支持。 叉支撑从最新的版本(0.7.0)移除,并使用下一个最旧的版本(0.6.6),它不(排序的)支持叉子似乎不起作用,至少在运行任何分布式的测试宝石,我已经试过(叉勺,并行测试,水润,Specjour,几乎所有的人)。 有趣的是,宝石的作者暗示,在自述,以Process.spawn是用于Process.fork可接受的解决方法。
我已经看到了很多的信息或者暗示,或说明完全是菌种可作为叉的替代品,在Windows上,使用Ruby 1.9。 我已经花了许多时间玩这个了相当数量的,基本上是试图取代Process.fork与Process.spawn几个引用的宝石,没有成功。 在我看来,也许这个行为相似,但不完全相同。 例如,目前还不清楚产卵实际拷贝以同样的方式叉呢,或者干脆整个过程是否创建与所提供的参数的新方法。 目前还不清楚,以产卵方法是否甚至接受另一个红宝石方法作为一个参数,或仅一个系统命令。 该文档似乎暗示它只是一个命令,但在方法似乎工作(排序的),但我可能不正确地做事。 我认为,对于一些事情,叉只是用来创建一个“便宜线”,在不支持线程以前的Ruby版本。 然而,似乎这些分布式测试宝石可以合法地依赖于fork()的全部功能,以保持该项目的状态,并为每个测试不加载整个红宝石环境。 这是我的正常程序的职责和经验之外的一点,所以我可能会作出一些不正确的假设。
所以,我的问题是,可以Process.spawn相对简单地用来实现相同的效果作为Process.fork,在所有情况下? 我开始怀疑没有,但如果是这样,可能有人请张贴的一个将如何去进行转换的一个例子吗?
编辑 :有一个常用的情况fork()
可以被替换为spawn()
-的fork()
- exec()
组合。 许多较旧的(现代)的UNIX应用程序,当他们想产生另一个过程中,会第一叉,然后再做一个exec
调用( exec
替换当前的进程与其他)。 这实际上并不需要fork()
,这就是为什么它可以替换spawn()
所以这:
if(!fork())
exec("dir")
end
可以替换为:
Process.spawn("dir")
如果任何宝石使用fork()
这样的,修复是容易的。 否则,它几乎是不可能的。
编辑 :之所以Win32的进程的执行fork()
不工作是,(据我可以从文档告诉),它基本上是 spawn()
这是不fork()
在所有。
不,我不认为这是可以做到。 你看, Process.spawn
使用默认的空白状态和本机代码的新方法。 所以,虽然我可以这样做Process.spawn('dir')
将开始运行一个新的空白工艺dir
,它不会复制任何当前进程的状态。 这只是给你的程序的连接是父 - 子连接。
你看, fork()
是一个非常低的水平通话。 例如,在Linux上,什么fork()
主要作用是这样的:首先,一个新的进程恰好与克隆寄存器状态下创建。 然后,Linux确实一个写入时复制引用到所有的父进程的页面。 那么Linux克隆其他进程的标志。 显然,所有这些操作只能由内核完成,Windows内核不具备的设施要做到这一点(而不能修补要么)。
从技术上讲,只有本机程序需要OS为某种fork()
样的支持。 任何代码层需要层的合作它上面做类似fork()
。 因此,虽然本机C代码需要的内核到餐桌的合作,红宝石理论上只需要解释的合作做一个叉。 然而,Ruby解释器不具有快照/恢复功能,这将是必然实现一个叉。 正因为如此,一般的Ruby叉由分叉解释本身,而不是Ruby程序来实现的。
所以,虽然如果你能修补Ruby解释器添加一个启动/停止和快照/恢复功能,你可以做到这一点,但在其他方面? 我不认为如此。
所以,你有什么选择? 这是我能想到的:
- 修补Ruby解释器
- 修补使用该代码
fork()
到也许使用线程或产卵 - 获得UNIX(我的建议是一个)
- 使用Cygwin
编辑1:我不会建议使用Cygwin的叉,因为它涉及到特殊的Cygwin进程表, 没有写入时复制,这使得它非常低效的。 此外,它涉及到很多来回跳跃和大量复制。 避免它,如果可能的。 此外,因为Windows不提供任何设施,以复制地址空间,叉很可能会失败,并且将相当多的时间(见这里 )。