각 요소를 처리해야 할 때 루비 스크립트 배열이 있습니다.
threads = []
elemets.each do |element|
threads.push(Thread.new{process(element)}}
end
threads.each { |aThread| aThread.join }
그러나 리소스 제한으로 인해 한 번에 네 가지 요소가 더 이상 처리되지 않으면 스크립트가 최적의 방식으로 작동합니다.
아니 나는 각 루프를 덤프하고 변수를 사용하여 4 요소를 계산 한 다음 기다릴 수 있다는 것을 알고 있지만 더 멋진 루비 방법이 있습니까?
답변
배열에 대해 4 개의 그룹으로 열거 할 수 있습니다.
>> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].each_slice(4) {|a| p a}
[1, 2, 3, 4]
[5, 6, 7, 8]
[9, 10, 11, 12]
그래서 당신은 다음과 같은 것을 시도 할 수 있습니다.
elements.each_slice(4) do | batch |
batch.each do | element |
threads.push(Thread.new{process(element)}}
end
(do stuff to check to see if the threads are done, otherwise wait )
end
그래도 필요한 것이 아닐 수도 있습니다. 오전 3시 이후에 일어나서 잠을 몇 시간 밖에 안 잤습니다. : /
답변
내가 올바르게 읽으면 한 번에 4 개 이상의 스레드를 처리하지 않기를 원합니다.
4 개의 스레드 만 시작하고 요소를 처리하기 위해 공유 큐 (표준 스레드 라이브러리의 일부)에서 모두 읽어야하는 것처럼 들립니다.
큐가 비어있을 때 스레드를 종료 할 수 있습니다.
배열을 4 개의 동일한 배열로 분할하고 각 스레드가 요소의 1/4을 처리하도록하면 각 요소가 동시에 처리된다고 가정합니다. 일부가 다른 것보다 오래 걸리면 일부 스레드가 일찍 완료됩니다.
큐를 사용하면 공유 큐가 비워 질 때까지 스레드가 멈추지 않으므로 더 효율적인 솔루션이라고 생각합니다.
다음은 코드를 기반으로하는 작업 프로그램입니다.
require 'thread'
elements = [1,2,3,4,5,6,7,8,9,10]
def process(element)
puts "working on #{element}"
sleep rand * 10
end
queue = Queue.new
elements.each{|e| queue << e }
threads = []
4.times do
threads << Thread.new do
while (e = queue.pop(true) rescue nil)
process(e)
end
end
end
threads.each {|t| t.join }
답변
다음 변형이 “4 개의 요소를 계산하는 변수”를 사용하는 것으로 간주되는지 또는 멋진 것으로 간주 될 수 있는지 확실하지 않지만 4 개 요소보다 크지 않은 크기의 조각으로 배열을 제공합니다.
x = (1..10).to_a
0.step(x.size - 1, 4) do |i|
# Choose one
p x.slice(i, 4)
p x[i, 4]
end
답변
레일에서는 더 읽기 쉬운 형식을 사용할 수 있습니다. in_groups_of
arr= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
arr.in_groups_of(4, false) {|a| p a}
결과:
[1, 2, 3, 4]
[5, 6, 7, 8]
[9, 10, 11]
에서 false를 지정 했으므로 마지막 행에는 3 개의 요소 만 in_group_of
있습니다. nil 또는 다른 값을 원하면 false를 해당 값으로 바꿀 수 있습니다.
답변
예,하지만 몇 가지 메서드 재정의를 수행해야합니다. 일반적인 접근 방식은 Array
다음과 같이 ‘/’를 재정의하는 것입니다.
class Array
def / len
a = []
each_with_index do |x,i|
a << [] if i % len == 0
a.last << x
end
a
end
end
정의 된대로 이제 다음을 쉽게 수행 할 수 있습니다.
foo = [1,2,3,4,5,6]
foo / 2
# Result is [[1,2], [3,4], [5,6]]