Fundamentals 38 min read

Master Python Concurrency: Threads, Processes, GIL, and Multiprocessing Explained

This article provides a comprehensive guide to Python concurrency, covering the fundamental differences between threads and processes, the impact of the Global Interpreter Lock, and detailed usage of the multiprocessing module with its various components and synchronization primitives.

21CTO
21CTO
21CTO
Master Python Concurrency: Threads, Processes, GIL, and Multiprocessing Explained

Thread and Process Differences

In operating systems, a process is the smallest unit of resource allocation, while a thread is the smallest unit of CPU scheduling. Multiple threads can run within a single process to perform different tasks concurrently.

Key Distinctions

Address space and resources: processes have independent address spaces; threads within the same process share memory.

Communication: processes use IPC mechanisms; threads can directly read/write shared data, requiring synchronization.

Scheduling and switching: thread context switches are much faster than process switches.

In modern OSes, threads are considered essential for concurrency.

Multi‑Process vs Multi‑Thread Comparison

Key points include data sharing, memory usage, creation overhead, programming complexity, reliability, and suitability for distributed systems.

Python Global Interpreter Lock (GIL)

The mechanism used by the CPython interpreter to assure that only one thread executes Python bytecode at a time. This simplifies the CPython implementation by making the object model implicitly safe against concurrent access.

The GIL ensures that only one thread runs Python bytecode simultaneously, which benefits single‑threaded performance and C extension integration but limits true parallelism on multi‑core CPUs.

Execution steps under the GIL:

Acquire GIL

Switch to a thread

Run until a bytecode limit or the thread yields

Set thread to sleep

Release GIL

Repeat

Python 3.2 introduced a timeout‑based GIL release, improving performance on single‑core systems but still causing thrashing on multi‑core CPUs.

Mitigating GIL Impact

Upgrade to newer Python versions with GIL improvements

Use multiprocessing instead of multithreading

Set CPU affinity for threads

Use GIL‑free interpreters like Jython or IronPython

Prefer I/O‑bound workloads for threading

Employ coroutines for efficient single‑threaded concurrency

Write performance‑critical parts in C/C++ extensions (with nogil)

Python Multiprocessing Package

The multiprocessing module provides a process‑based parallelism API that mirrors the threading interface, allowing easy migration from threads to processes.

Background

Multiprocessing was created to overcome GIL limitations and to provide a cross‑platform API for process creation, especially on Windows where fork() is unavailable.

import os
print('Process (%s) start...' % os.getpid())
pid = os.fork()
if pid == 0:
    print('I am child process (%s) and my parent is %s.' % (os.getpid(), os.getppid()))
else:
    print('Parent process %s created child %s.' % (os.getpid(), pid))

Core Components

Process : Create and manage a process.

Pool : Manage a pool of worker processes.

Queue , JoinableQueue : Inter‑process communication queues.

Pipe : Two‑ended communication channel.

Value , Array : Shared memory primitives.

Manager : Server process providing shared objects like list, dict, etc.

Process Example

from multiprocessing import Process
import os

def run_proc(name):
    print('Run child process %s (%s)...' % (name, os.getpid()))

if __name__ == '__main__':
    print('Parent process %s.' % os.getpid())
    p = Process(target=run_proc, args=('test',))
    p.start()
    p.join()
    print('Child process end.')

Pool Example

from multiprocessing import Pool

def test(i):
    print(i)

if __name__ == '__main__':
    pool = Pool(8)
    pool.map(test, range(100))
    pool.close()
    pool.join()

Queue Example

from multiprocessing import Process, Queue
import os, time, random

def write(q):
    print('Process to write: %s' % os.getpid())
    for v in ['A', 'B', 'C']:
        print('Put %s to queue...' % v)
        q.put(v)
        time.sleep(random.random())

def read(q):
    print('Process to read: %s' % os.getpid())
    while True:
        v = q.get(True)
        print('Get %s from queue.' % v)

if __name__ == '__main__':
    q = Queue()
    pw = Process(target=write, args=(q,))
    pr = Process(target=read, args=(q,))
    pw.start()
    pr.start()
    pw.join()
    pr.terminate()

Synchronization Primitives

Lock : Mutual exclusion.

RLock : Re‑entrant lock.

Semaphore : Counting semaphore for limited concurrent access.

Condition : Advanced lock with wait/notify.

Event : Simple flag for signaling.

Lock Example

from multiprocessing import Process, Lock

def l(lock, num):
    lock.acquire()
    print('Hello Num: %s' % num)
    lock.release()

if __name__ == '__main__':
    lock = Lock()
    for num in range(20):
        Process(target=l, args=(lock, num)).start()

Concurrent.futures

Python 3.2+ provides ThreadPoolExecutor and ProcessPoolExecutor for high‑level asynchronous execution.

from concurrent import futures
import time

def test(num):
    return time.ctime(), num

with futures.ThreadPoolExecutor(max_workers=1) as executor:
    future = executor.submit(test, 1)
    print(future.result())
Thread vs Process diagram
Thread vs Process diagram
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

concurrencythreadingGILmultiprocessing
21CTO
Written by

21CTO

21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.