Có một lớp Queue
trong thread
trong thư viện chuẩn. Sử dụng mà bạn có thể làm điều gì đó như thế này:
require 'thread'
queue = Queue.new
threads = []
# add work to the queue
queue << work_unit
4.times do
threads << Thread.new do
# loop until there are no more things to do
until queue.empty?
# pop with the non-blocking flag set, this raises
# an exception if the queue is empty, in which case
# work_unit will be set to nil
work_unit = queue.pop(true) rescue nil
if work_unit
# do work
end
end
# when there is no more work, the thread will stop
end
end
# wait until all threads have completed processing
threads.each { |t| t.join }
Lý do tôi bật với cờ non-blocking là giữa và pop until queue.empty?
thread khác có thể đã pop'ed hàng đợi, vì vậy trừ khi non-blocking cờ được thiết lập, chúng tôi có thể gặp khó khăn ở dòng đó mãi mãi.
Nếu bạn đang sử dụng MRI, trình thông dịch Ruby mặc định, hãy nhớ rằng các chuỗi sẽ không hoàn toàn đồng thời. Nếu công việc của bạn là CPU bị ràng buộc bạn cũng có thể chạy đơn luồng. Nếu bạn có một số hoạt động mà khối trên IO bạn có thể nhận được một số song song, nhưng YMMV. Ngoài ra, bạn có thể sử dụng một thông dịch viên cho phép đồng thời đầy đủ, chẳng hạn như jRuby hoặc Rubinius.
Trong cuốc, nó gợi ý có 4 ': END_OF_WORK' 'work_unit's thay vì có một cửa sổ pop non-blocking. Ngoài ra, tuyên bố cuối cùng của bạn về các chủ đề không có CPU chạy đồng thời áp dụng cho YARV, nhưng không phải để JRuby. –
@AndrewGrimm, tôi thích câu trả lời này bởi vì đôi khi bạn muốn có một hàng đợi công việc và các chủ đề kéo dài xung quanh để làm việc bất cứ khi nào một mục công việc mới được thêm vào. – akostadinov