Understanding thread.join(timeout)

FrancescoN picture FrancescoN · Jul 21, 2014 · Viewed 17.2k times · Source

So the timeout param, for a thread, should stop the thread after timeout seconds (if it hasn't terminated yet).

In my software I'm trying to replace a Queue.Queue.join() (it contains an item for every thread: each thread will run Queue.Queue.task_done()) that could stop the software if a thread doesn't terminate. So if a thread, among other 50, doesn't terminate then it is all freezed.

I want that every thread stops in 5 seconds, for example. So i will start each thread with timeout of 5 seconds. Is it correct?

CODE

import threading
import time

def tt(name, num):
    while True:
        num += 0.5
        print 'thread ' + str(name) + ' at time ' + str(num)
        time.sleep(0.5)


for i in range(3):
    t=threading.Thread(target=tt, args=(i, 0))
    t.setDaemon(True)
    t.start()
    t.join(timeout=1)

print 'end'

RESULT

It is not properly working.. every thread should stop after 1 second. Thread 0 stops after 3 secs, thread 1 after 2 secs.

thread 0 at time 0.5
thread 0 at time 1.0
thread 1 at time 0.5
thread 0 at time 1.5
thread 0 at time 2.0
thread 1 at time 1.0
thread 2 at time 0.5
thread 0 at time 2.5
thread 1 at time 1.5
thread 2 at time 1.0thread 1 at time 2.0

thread 0 at time 3.0
end

Answer

dano picture dano · Jul 21, 2014

You're misunderstanding what timeout does. It just tells join how long to wait for the thread to stop. If the thread is still running after the timeout expires, the join call ends, but the thread keeps running.

From the docs:

When the timeout argument is present and not None, it should be a floating point number specifying a timeout for the operation in seconds (or fractions thereof). As join() always returns None, you must call isAlive() after join() to decide whether a timeout happened – if the thread is still alive, the join() call timed out.