python – join all threads after start_new_thread

Question:

When using the thread library,
Is there a way to join all threads that were created by start_new_threads ?

for example:

try:    
    import thread 
except ImportError:
    import _thread as thread #Py3K changed it.

for url in url_ip_hash.keys(): 
    thread.start_new_thread(check_url, (url,))

How can join all threads ?

Asked By: gal

||

Answers:

Is there a reason you’re using thread instead of the recommended Threading module? If not, you should rather use the threading.Thread objects which have a join method:

from threading import Thread


def check_url(url):
    # some code

threads = []
for url in url_ip_hash.keys():
    t = Thread(target=check_url, args=(url, ))
    t.start()
    threads.append(t)

# join all threads
for t in threads:
    t.join()
Answered By: Bastian Venthur

If you want to use _thread instead of threading.Thread, you can implement mutexes to know when your other threads are complete.

# make as many lock objects as you have threads ==> len(url_ip_hash.keys())
exitmutexes = [thread.allocate_lock() for _ in range of len(url_ip_hash.keys())]

def check_url(threadnum, url):
    "enter your code here"""
    exitmutexes[threadnum].acquire()

for url in url_ip_hash.keys(): 
    thread.start_new_thread(check_url, (url,))

# the mutex's lock method can be used to check its state. 
# continues in while loop until lock acquired for every exitmutex
for mutex in exitmutexes:
    while not mutex.locked(): pass
print('Program exited successfully.')

Another way is to make a global boolean list, assigning False to every item in the list, and switching them to True when your thread exits.

exitstatus = [False] * len(url_ip_hash.keys)

def check_url(threadnum, url):
    """ Enter your code here"""
    exitstatus[threadnum] = True

for url in url_ip_hash.keys(): 
    thread.start_new_thread(check_url, (threadnum, url))

while False in exitstatus: pass
print('Program exited successfully.')

As you can see, as mentioned earlier, it’s much simpler to use the threading.Thread module and performing a .join. Hope that helps.

Answered By: trozzel

Coding in micropython instead of plain python is one of the reasons one could need to use the _thread module instead of threading.

If that’s your case, another alternative besides using _thread and implementing the join yourself, is to use coroutines, available in the asyncio module for python and uasyncio for micropython.

For example, if you simple want to wait for the function to execute, you can just call asyncio.run(your_function()).

Answered By: vrcoelho
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.