I want to call a common enumerator from different threads. When I do the following,
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
it raises an error:
Fiber called across threads.
when enum
is called from t2
after once being called from t1
.
I am guessing that atomicity of an operation on an enumerator/fiber is relevant here, but am not fully sure. If that is the issue, then exclusively-locking the enumerator/fiber while in use shall solve the problem, and I don't know why calling an enumerator/fiber across threads is prohibited in general. If an alternative can be provided by using locking, that would satisfy my need.
Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception.
Within a process or program, we can run multiple threads concurrently to improve the performance. Threads, unlike heavyweight process, are lightweight and run inside a single process – they share the same address space, the resources allocated and the environment of that process.
Bounding and blocking functionality for any type. Thread-safe implementation of a dictionary of key-value pairs. Thread-safe implementation of a FIFO (first-in, first-out) queue. Thread-safe implementation of a LIFO (last-in, first-out) stack.
CSharp Online Training Concurrent namespace. The namespace has numerous collection classes. These classes are both thread-safe and scalable.
You can use 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With