我试图将数组传递到一个函数,并并行地对数组的每个成员运行该函数,而不是对成员进行迭代。完成此操作的最佳方法是什么?我成功使用了过程。播种,但这需要打开一个新的外壳。有什么想法吗?
谢谢!
您可以使用Thread
(请参阅https://ruby-doc.org/core-2.4.0/thread.html)
例如:
threads = []
your_array.each do |item|
threads << Thread.new do
# do operation on item. Each one is handled in a new thread
end
end
threads.map(&:join) # wait for all threads to finish
值得一提的是产卵新线程的开销。如果您的数组很大,则可能一次选择 n 项目(例如使用each_cons
。#method-i-each_cons),并让每个线程处理一个小批次,而不是单个项目。
您可以使您散发出Ruby Gem。这为 fork (到多个进程)或 thread (到多个线程)的选项提供了选项。
。如果要使用线程实现并行执行,则使用(我们可以打开的数字线程受到Rails应用程序可用的连接限制):
threads = []
your_array.each do |item|
Spawnling.new(:method => :thread) do
#something
end
end
其他可以使用多个进程实现并行执行,然后使用(我们可以打开的数字叉子受到serves中可用的资源限制了应用程序运行):
threads = []
your_array.each do |item|
Spawnling.new(:method => :fork) do
#something
end
end
宝石的文档在这里
我不会为每个数组创建一个新线程。我将为系统上的每个处理器创建一个(如果您想变得友善,可能会更少),然后在其中分配工作。
number_of_threads = 4
items_per_thread = work_items_array.length.fdiv(number_of_threads).ceil
work_items.each_slice(items_per_thread) do |items|
Thread.new do
items.each do |item|
process_item(item)
end
end
end
如果所有项目都接近同一时间执行,则可以很好地工作。如果他们不这样做,那么您可以在一个线程结束之前很早就完成另一个线程的情况。在这种情况下,您可能想创建一个项目队列,并让每个线程从队列中拉出一个项目进行工作。您将需要线程安全队列实现,例如Ruby提供的。
类似:
queue = Queue.new
work_items.each { |item| queue << item }
number_of_threads.times do |i|
Thread.new do
begin
while item=queue.pop(true) do
process_item(item)
end
rescue ThreadError
# thread is empty
end
end
end
这也有一个优势,您可以在处理后可以将项目添加到队列中。