Ruby并行每个循环

时间:2014-04-01 21:50:36

标签: ruby multithreading parallel-processing

我有以下代码:

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

如何强制放置,就像它们通常会分开一样。

2 个答案:

答案 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不包含任何例外。