Threading on a list of arguments

Question:

I would like to pass a list of values and have each of them passed as an independent Thread:

For example:

import time
import threading

list_args = [arg1, arg2, arg3, ...., argn]

# Code to execute in an independent thread
import time
def countdown(n):
    while n > 0:
        print('T-minus', n)
        n -= 1
        time.sleep(0.5)


# Create and launch a thread
t1 = threading.Thread(target=countdown, args=(arg1,))
t2 = threading.Thread(target=countdown, args=(arg2,))
.
.
.
tn = threading.Thread(target=countdown, args=(argn,))
t1.start(); t2.start(); tn.start()
Asked By: Bob R

||

Answers:

import time
import threading

list_args = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

# Code to execute in an independent thread
def countdown(n):
    while n > 0:
        print('T-minus', n)
        n -= 1
        time.sleep(0.5)


# Create and launch a thread
for item in list_args:
    thread = threading.Thread(target=countdown, args=(item,))
    thread.start()
Answered By: Yoriz

Quick fix

Call .join() on each of your t1, t2, etc. threads at the end.

Details

I suspect your real question is ‘why isn’t countdown being called?’ The Thread.join() method causes the main thread to wait for other threads to finish executing before proceeding. Without it, once the main thread finishes, it terminates the whole process.

In your program when the main thread completes execution, the process is terminated along with all its threads, before the latter can call their countdown functions.

Other issues:

  1. It’s best to include a minimum working example. Your code cannot execute as written.

  2. Normally some sort of data structure is used to manage threads. This is nice because it makes the code more compact, general, and reusable.

  3. You needn’t import time twice.

This might be close to what you want:

import time
import threading

list_args = [1,2,3]

def countdown(n):
    while n > 0:
        print('T-minus', n)
        n -= 1
        time.sleep(0.5)


# Create and launch a thread
threads = []
for arg in list_args:
    t = threading.Thread(target=countdown,args=(arg,))
    t.start()
    threads.append(t)

for thread in threads:
    thread.join()
Answered By: rjonnal

I think this will do what you’re describing:

for a in list_args:
    threading.Thread(target=countdown, args=(a,)).start()
Answered By: Gary Wisniewski

You can add all threads to a list to be independent from the number of arguments. At the end of your main program, you have to join all threads. Otherwise the main thread exits and terminates all other threads.

Working code:

import time
import threading

# create list [0, 1, ..., 9] as argument list
list_args = range(10)

# Code to execute in an independent thread
def countdown(n):
    while n > 0:
        print('T-minus', n)
        n -= 1
        time.sleep(0.5)

if __name__ == '__main__':
    threads = []

    # create threads
    for arg in list_args:
        threads.append(threading.Thread(target=countdown, args=(arg,)))

    # start threads
    for thread in threads:
        print("start")
        thread.start()

    # join threads (let main thread wait until all other threads ended)
    for thread in threads:
        thread.join()

    print("finished!")
Answered By: Felix