Совместное использование перечислителя между потоками
Я хочу вызвать общий счетчик из разных тем. Когда я делаю следующее,
enum = (0..1000).to_enum
t1 = Thread.new do
p enum.next
sleep(1)
end
t2 = Thread.new do
p enum.next
sleep(1)
end
t1.join
t2.join
это вызывает ошибку:
Fiber called across threads.
когда enum
вызывается из t2
после того, как однажды позвонили из t1
,
- Почему Ruby не позволяет вызывать перечислитель (или волокно) между потоками, и
- Есть ли альтернативный способ предоставить аналогичную функцию?
Я предполагаю, что атомарность операции на счетчике / волокне имеет отношение здесь, но я не совсем уверен. Если это проблема, то исключительная блокировка перечислителя / оптоволокна во время использования должна решить проблему, и я не знаю, почему вызов перечислителя / оптоволокна через потоки вообще запрещен. Если альтернатива может быть предоставлена с помощью блокировки, это удовлетворит мою потребность.
1 ответ
Ты можешь использовать Queue
queue = Queue.new
(0..1000).map(&queue.method(:push))
t1 = Thread.new do
while !queue.empty?
p queue.pop(true)
sleep(0.1)
end
end
t2 = Thread.new do
while !queue.empty?
p queue.pop(true)
sleep(0.1)
end
end
t1.join
t2.join