labyrinth
labyrinth

Reputation: 13936

Why doesn't main code between first joined thread execute before a second thread is joined?

I'm learning about threads and have the following code:

def timefunc(delay)
  i = 0
  while i <= 2
    puts "func w/ #{delay} second delay at: #{Time.now}"
    puts "Thread priority: #{Thread.current.priority}"
    sleep(delay)
    i = i + 1
  end
end

puts "Started program at #{Time.now}"

t1 = Thread.new{timefunc(2)}
t2 = Thread.new{timefunc(1)}

puts "before joins"

t1.join
puts "between joins"
t2.join

puts "after joins"

puts "Ended program at #{Time.now}"

The output was:

Started program at 2018-05-04 10:23:51 -0600
before joins
func w/ 1 second delay at: 2018-05-04 10:23:51 -0600
func w/ 2 second delay at: 2018-05-04 10:23:51 -0600
Thread priority: 0
Thread priority: 0
func w/ 1 second delay at: 2018-05-04 10:23:52 -0600
Thread priority: 0
func w/ 2 second delay at: 2018-05-04 10:23:53 -0600
Thread priority: 0
func w/ 1 second delay at: 2018-05-04 10:23:53 -0600
Thread priority: 0
func w/ 2 second delay at: 2018-05-04 10:23:55 -0600
Thread priority: 0
between joins
after joins
Ended program at 2018-05-04 10:23:57 -0600

I figured that thread started in t1.join would do all of its work before letting main do puts "between joins", but I was surprised when the t2.join got executed first as well. Does the interpreter look ahead for any join statements and run them first? How does this work?

Upvotes: 1

Views: 32

Answers (1)

Max
Max

Reputation: 22325

I think you might find this change enlightening:

sleep 10
puts "before joins"

Threads are allowed to start doing work the moment they are created, so inserting this one sleep allows both threads to finish all of their work before the main thread does anything else.

t1.join is similar, but instead of waiting 10 seconds, it instead says "don't let the current thread proceed until t1 is done". So it is "doing all of its work": it waits for t1 to finish, by which time t2 is also done. So you see the between and after outputs back-to-back.

Upvotes: 2

Related Questions