我有以下代码:
FTP ... do |ftp|
files.each do |file|
...
ftp.put(file)
sleep 1
end
end
我想以单独的线程或某种并行的方式运行每个文件。这样做的正确方法是什么?这是对的吗?
这是我对parallel gem
的尝试FTP ... do |ftp|
Parallel.map(files) do |file|
...
ftp.put(file)
sleep 1
end
end
并行的问题是put / outputs可以同时发生:
as = [1,2,3,4,5,6,7,8]
results = Parallel.map(as) do |a|
puts a
end
如何强制放置,就像它们通常会分开一样。
答案 0 :(得分:1)
并行化的重点是同时运行。但是,如果您希望按顺序运行某些代码的过程的某些部分,则可以使用mutex
,例如:
semaphore = Mutex.new
as = [1,2,3,4,5,6,7,8]
results = Parallel.map(as, in_threads: 3) do |a|
# Parallel stuff
sleep rand
semaphore.synchronize {
# Sequential stuff
puts a
}
# Parallel stuff
sleep rand
end
您会看到它正确打印的内容,但不是必须以相同的顺序打印。我使用in_threads
代替in_processes
(默认),因为Mutex
不能处理进程。如果您确实需要流程,请参阅下面的替代方案。
<强>参考文献:强>
答案 1 :(得分:0)
为了保持简单,这就是我对内置Thread
所做的事情:
results = files.map do |file|
result = Thread.new do
ftp.put(file)
end
end
请注意,此代码假定ftp.put(file)
安全返回。如果不能保证,那么你必须自己通过在超时块中包装调用并让每个线程返回异常(如果抛出一个然后在循环的最后进行阻塞检查)来做到这一点。看到results
不包含任何例外。