← Back to Python Course | Chapter 11: Advanced Python | Lesson 5 of 12

Python Threading

Threading lets a program do several jobs at the same time, like a cook stirring soup while the oven heats. Each thread is one line of work running alongside the others.
Syntax
python
import threading

thread = threading.Thread(target=function_name, args=(arg,))
thread.start()
thread.join()

What is Threading?

Threading lets a program run multiple pieces of code seemingly at the same time within one process, which is most useful for I/O-bound tasks (waiting on network requests or disk reads) where a thread can idle without blocking the rest of the program -- CPU-bound work benefits far less due to Python's GIL.

Example: What is Threading?

python
import threading
print(threading.active_count())

Creating a Basic Thread

Creating a thread means instantiating threading.Thread(target=some_function) and then calling .start() on it -- start() launches the thread running concurrently with the rest of your program, rather than running it immediately and blocking like a normal function call would.

Example: Creating a Basic Thread

python
import threading

def task():
    print("Running in a thread")

t = threading.Thread(target=task)
t.start()  # starts running concurrently
t.join()  # waits for the thread to finish

Joining Threads

By default, your main program keeps executing immediately after start() without waiting for the thread to finish -- calling .join() on a thread object blocks the calling code until that specific thread has completed, which matters when later code depends on the thread's work being done.

Example: Joining Threads

python
import threading

def task():
    print("Thread work done")

t = threading.Thread(target=task)
t.start()
t.join()  # blocks here until the thread completes
print("Main continues after thread finishes")

Threading with Arguments

The args parameter to Thread() accepts a tuple of arguments to pass into the target function when the thread starts -- Thread(target=download, args=(url,)) is how you launch download(url) to run concurrently rather than calling it directly.

Example: Threading with Arguments

python
import threading

def greet(name):
    print("Hello,", name)

t = threading.Thread(target=greet, args=("Alex",))  # args are passed to greet when the thread starts
t.start()
t.join()

Thread Safety and Locks

Because threads in the same process share memory, two threads modifying the same variable at the same moment can corrupt it through a race condition -- threading.Lock() lets you mark a section of code so only one thread can execute it at a time, preventing that kind of collision.

Example: Thread Safety and Locks

python
import threading

counter = 0
lock = threading.Lock()

def increment():
    global counter
    with lock:  # only one thread runs this block at a time
        counter += 1

threads = [threading.Thread(target=increment) for _ in range(5)]
for t in threads:
    t.start()
for t in threads:
    t.join()
print(counter)
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Calling t.run() instead of t.start(), which runs the function in the current thread and not a new one.
  2. Writing Thread(target=work()), which calls the function right away; pass target=work instead.
  3. Updating a shared variable from several threads without a Lock, which causes race conditions.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.