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

Python Threading

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()
t.join()

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()
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",))
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:
        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)

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.