Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python threading - do something while join()

Python 2.6.6

I hava a list of threads to be executed and the main code will wait (Threading.join()) until they're all finished.

>>> for thread in threadList:
...     thread.start()
>>> for t in threadList:
...     t.join()

Is there a way to print messages like "running..." while the main code waits the end of the threads?

I want to print the same thing ("running...") second after second until the threads are all done.

Thanks.


SOLVED

Implemented solution:

>>> for thread in threadList:
...     thread.start()
>>> string = "running"
>>> while any(t.is_alive() for t in threadList):
...    sys.stdout.write("\r%s" % string)
...    sys.stdout.flush()
...    string = string + "."                     #this may not be the best way
...    time.sleep(0.5)

In my case, the extra time of "time.sleep(0.5)" is not an issue, although it's not the most recommended.

This generates the output:

running........

The dots after "running" will be printed one after one, on the same line, while there is any thread alive. Exactly as I expected!

Based on the answers of @Manuel Jacob and @Alex Hall.

like image 689
HeitorLima Avatar asked Nov 24 '25 10:11

HeitorLima


2 Answers

Thread.join() is blocking by design. Instead of using Thread.join(), you could periodically call Thread.is_alive().

Your example adapted:

for thread in threadList:
    thread.start()
while any(thread.is_alive() for thread in threadList):
    print('running...')
    time.sleep(1)

As was pointed out in the comments, this can cause up to one second of extra delay, when the last thread finishes during the sleep.

like image 109
Manuel Jacob Avatar answered Nov 26 '25 00:11

Manuel Jacob


from time import sleep
from threading import Thread

threadList = [Thread(target=lambda: sleep(3)), Thread(target=lambda: sleep(5))]

for thread in threadList:
    thread.start()

def check_running():
    while True:
        alive = sum(thread.is_alive() for thread in threadList)
        if not alive:
            break
        print '%s threads still running...' % alive
        sleep(1)

Thread(target=check_running).start()

for t in threadList:
    t.join()

Output:

2 threads still running...
2 threads still running...
2 threads still running...
1 threads still running...
1 threads still running...

Alternatively:

from time import sleep
from threading import Thread

threadList = [Thread(target=lambda: sleep(3), name='Alice'), Thread(target=lambda: sleep(5), name='Bob')]

for thread in threadList:
    thread.start()

for t in threadList:
    while True:
        t.join(timeout=1)
        if not t.is_alive():
            break
        print('%s is still running...' % t.name)

Output:

Alice is still running...
Alice is still running...
Bob is still running...
like image 30
Alex Hall Avatar answered Nov 25 '25 23:11

Alex Hall