如何在单个 ruby 脚本中写入和读取同一个命名管道?
How to write to and read from the same named pipe in a single ruby script?
编辑:我想我解决了这个问题:https://gist.github.com/niuage/c0637b8dd10549a12b6a223dbd5f158a
我可能遗漏了 Process.wait,因此创建了很多僵尸进程。
我有一段代码大部分时间都在工作,但 "locks" 一段时间后它自己,可能是因为竞争条件。
我的代码
pipe = "goals.png"
(1..100).each do |time|
fork do
# This runs ffmpeg, and gets it to write 1 frame of a video to the pipe 'goals.png'
print "before ffmpeg"
`#{ffmpeg(time, score_crop_options, pipe)}`
exit
end
# Reads from 'pipe'
print "before read"
blob = File.read(pipe)
image = Rocket::Image.from_blob(blob)
# do stuff with image
end
注意事项:
#{ffmpeg(time, pipe)}
写入管道,并一直阻塞直到从管道读取某些内容
File.read(pipe) 一直阻塞,直到有东西写入 pipe
我的问题
编辑:当脚本被锁定时,我尝试从另一个脚本读取管道,我得到 zsh: fork failed: resource temporarily unavailable
。这可能是一个很好的线索...
大多数时候,File.read(pipe)
在 fork 中的代码之前执行,所以它工作得很好,但过了一会儿脚本就停止了:它打印 "before ffmpeg"
并且永远不会到达 "before read"
...
首先,我应该使用线程而不是 fork 吗?我可以控制 2 个语句(读取和写入)获得 运行 的顺序以避免竞争条件吗?或者也许它甚至与比赛条件无关,我错过了什么?
这个问题不是由竞争条件引起的,而是僵尸进程太多,因为我没有调用 Process.wait
The parent process should use Process.wait to collect the termination statuses of its children or use Process.detach to register disinterest in their status; otherwise, the operating system may accumulate zombie processes.
这就是为什么我在尝试从另一个脚本中读取管道时得到 zsh: fork failed: resource temporarily unavailable
的原因。
这里有一些有用的东西:
(1..100) do
if fork
# Parent
image = read_image(pipe)
# do stuff with image
Process.wait # I think that's what was missing previously
else
# Child
Open3.popen3(command(time, score_crop_options, pipe)) do |stdin, stdout, stderr, wait_thr|
# stuff
end
exit!(0)
end
end
编辑:我想我解决了这个问题:https://gist.github.com/niuage/c0637b8dd10549a12b6a223dbd5f158a
我可能遗漏了 Process.wait,因此创建了很多僵尸进程。
我有一段代码大部分时间都在工作,但 "locks" 一段时间后它自己,可能是因为竞争条件。
我的代码
pipe = "goals.png"
(1..100).each do |time|
fork do
# This runs ffmpeg, and gets it to write 1 frame of a video to the pipe 'goals.png'
print "before ffmpeg"
`#{ffmpeg(time, score_crop_options, pipe)}`
exit
end
# Reads from 'pipe'
print "before read"
blob = File.read(pipe)
image = Rocket::Image.from_blob(blob)
# do stuff with image
end
注意事项:
#{ffmpeg(time, pipe)}
写入管道,并一直阻塞直到从管道读取某些内容File.read(pipe) 一直阻塞,直到有东西写入 pipe
我的问题
编辑:当脚本被锁定时,我尝试从另一个脚本读取管道,我得到 zsh: fork failed: resource temporarily unavailable
。这可能是一个很好的线索...
大多数时候,File.read(pipe)
在 fork 中的代码之前执行,所以它工作得很好,但过了一会儿脚本就停止了:它打印 "before ffmpeg"
并且永远不会到达 "before read"
...
首先,我应该使用线程而不是 fork 吗?我可以控制 2 个语句(读取和写入)获得 运行 的顺序以避免竞争条件吗?或者也许它甚至与比赛条件无关,我错过了什么?
这个问题不是由竞争条件引起的,而是僵尸进程太多,因为我没有调用 Process.wait
The parent process should use Process.wait to collect the termination statuses of its children or use Process.detach to register disinterest in their status; otherwise, the operating system may accumulate zombie processes.
这就是为什么我在尝试从另一个脚本中读取管道时得到 zsh: fork failed: resource temporarily unavailable
的原因。
这里有一些有用的东西:
(1..100) do
if fork
# Parent
image = read_image(pipe)
# do stuff with image
Process.wait # I think that's what was missing previously
else
# Child
Open3.popen3(command(time, score_crop_options, pipe)) do |stdin, stdout, stderr, wait_thr|
# stuff
end
exit!(0)
end
end