This class watches for termination of multiple threads. Basic functionality (wait until specified threads have terminated) can be accessed through the class method ThreadsWait::all_waits
. Finer control can be gained using instance methods.
Example:
ThreadsWait.all_waits(thr1, thr2, ...) do |t| STDERR.puts "Thread #{t} has terminated." end th = ThreadsWait.new(thread1,...) th.next_wait # next one to be done
Returns the array of threads that have not terminated yet.
# File tmp/rubies/ruby-2.6.10/lib/thwait.rb, line 36
def ThreadsWait.all_waits(*threads) # :yield: thread
tw = ThreadsWait.new(*threads)
if block_given?
tw.all_waits do |th|
yield th
end
else
tw.all_waits
end
end
Waits until all specified threads have terminated. If a block is provided, it is executed for each thread as they terminate.
# File tmp/rubies/ruby-2.6.10/lib/thwait.rb, line 51
def initialize(*threads)
@threads = []
@wait_queue = Thread::Queue.new
join_nowait(*threads) unless threads.empty?
end
Creates a ThreadsWait
object, specifying the threads to wait on. Non-blocking.
# File tmp/rubies/ruby-2.6.10/lib/thwait.rb, line 124
def all_waits
until @threads.empty?
th = next_wait
yield th if block_given?
end
end
Waits until all of the specified threads are terminated. If a block is supplied for the method, it is executed for each thread termination.
Raises exceptions in the same manner as next_wait
.
# File tmp/rubies/ruby-2.6.10/lib/thwait.rb, line 63
def empty?
@threads.empty?
end
Returns true
if there are no threads in the pool still running.
# File tmp/rubies/ruby-2.6.10/lib/thwait.rb, line 70
def finished?
!@wait_queue.empty?
end
Returns true
if any thread has terminated and is ready to be collected.
# File tmp/rubies/ruby-2.6.10/lib/thwait.rb, line 78
def join(*threads)
join_nowait(*threads)
next_wait
end
Waits for specified threads to terminate, and returns when one of the threads terminated.
# File tmp/rubies/ruby-2.6.10/lib/thwait.rb, line 87
def join_nowait(*threads)
threads.flatten!
@threads.concat threads
for th in threads
Thread.start(th) do |t|
begin
t.join
ensure
@wait_queue.push t
end
end
end
end
Specifies the threads that this object will wait for, but does not actually wait.
# File tmp/rubies/ruby-2.6.10/lib/thwait.rb, line 108
def next_wait(nonblock = nil)
ThreadsWait.fail ErrNoWaitingThread if @threads.empty?
begin
@threads.delete(th = @wait_queue.pop(nonblock))
th
rescue ThreadError
ThreadsWait.fail ErrNoFinishedThread
end
end
Waits until any of the specified threads has terminated, and returns the one that does.
If there is no thread to wait, raises ErrNoWaitingThread
. If nonblock
is true, and there is no terminated thread, raises ErrNoFinishedThread
.