简体   繁体   English

Ruby并行每个循环

[英]Ruby Parallel each loop

I have a the following code: 我有以下代码:

FTP ... do |ftp| 
  files.each do |file| 
  ...
  ftp.put(file)
  sleep 1
  end 
end 

I'd like to run the each file in a separate thread or some parallel way. 我想以单独的线程或某种并行的方式运行每个文件。 What's the correct way to do this? 这样做的正确方法是什么? Would this be right? 这是对的吗?

Here's my try on the parallel gem 这是我对并行宝石的尝试

FTP ... do |ftp| 
  Parallel.map(files) do |file| 
  ...
  ftp.put(file)
  sleep 1
  end 
end 

The issue with parallel is puts/outputs can occur at the same time like so: 并行的问题是put / outputs可以同时发生,如下所示:

as = [1,2,3,4,5,6,7,8]
results = Parallel.map(as) do |a|
  puts a
end

How can I force puts to occur like they normally would line separated. 我怎样才能强制看跌,就像他们通常会分开一样。

The whole point of parallelization is to run at the same time. 并行化的全部要点是同时运行。 But if there's some part of the process that you'd like to run some of the code sequentially you could use a mutex like: 但是,如果您希望按顺序运行某些代码的过程的某些部分,则可以使用如下的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

You'll see that it prints stuff correctly but not necesarily in the same order. 你会看到它正确打印的东西,但不是必须以相同的顺序打印。 I used in_threads instead of in_processes (default) because Mutex doesn't work with processes. 我使用in_threads而不是in_processes (默认),因为Mutex不能与进程一起使用。 See below for an alternative if you do need processes. 如果您确实需要流程,请参阅下面的替代方案。

References: 参考文献:

In the interest of keeping it simple, here's what I'd do with built-in Thread : 为了保持简单,这就是我对内置Thread所做的事情:

results = files.map do |file|
  result = Thread.new do
    ftp.put(file)
  end
end

Note that this code assumes that ftp.put(file) returns safely. 请注意,此代码假定ftp.put(file)安全返回。 If that isn't guaranteed, you'll have to do that yourself by wrapping calls in a timeout block and have each thread return an exception if one is thrown and then at the very end of the loop have a blocking check to see that results does not contain any exceptions. 如果不能保证,你必须自己通过在超时块中包装调用并让每个线程返回异常(如果抛出一个)然后在循环的最后进行阻塞检查以查看results不包含任何例外。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM