← 返回首页
🚀

并发编程入门

📂 python ⏱ 2 min 217 words

并发编程入门

Python并发编程是处理多任务的核心技术。理解GIL的限制,以及何时选择多线程或多进程,是编写高效并发程序的关键。

GIL(全局解释器锁)

GIL是CPython解释器中的一个互斥锁,确保同一时刻只有一个线程执行Python字节码:

import threading
import time

counter = 0

def count_up():
    global counter
    for _ in range(100000):
        counter += 1

# 多线程不安全!
threads = [threading.Thread(target=count_up) for _ in range(4)]
for t in threads:
    t.start()
for t in threads:
    t.join()

print(counter)  # 结果不确定,小于400000

GIL的存在意味着CPU密集型任务使用多线程无法真正并行。

threading 模块

多线程适合I/O密集型任务:

import threading
import time

def io_task(name, duration):
    """模拟I/O操作"""
    print(f"{name} 开始")
    time.sleep(duration)
    print(f"{name} 完成")

# 创建线程
threads = []
for i in range(3):
    t = threading.Thread(target=io_task, args=(f"线程{i}", 2))
    threads.append(t)
    t.start()

for t in threads:
    t.join()

print("所有线程完成")
# 总耗时约2秒,而非6秒

multiprocessing 模块

多进程适合CPU密集型任务:

import multiprocessing
import time

def cpu_task(n):
    """CPU密集型任务"""
    return sum(i * i for i in range(n))

if __name__ == "__main__":
    numbers = [10**7] * 4

    start = time.time()
    results = [cpu_task(n) for n in numbers]
    print(f"串行: {time.time() - start:.2f}秒")

    start = time.time()
    with multiprocessing.Pool(4) as pool:
        results = pool.map(cpu_task, numbers)
    print(f"并行: {time.time() - start:.2f}秒")

threading vs multiprocessing

特性 threading multiprocessing
内存共享 共享内存 独立内存空间
适用场景 I/O密集型 CPU密集型
创建开销
通信方式 共享变量 Queue/Pipe
GIL影响 受GIL限制 不受GIL限制

线程安全

import threading
import time

# 使用锁保证线程安全
lock = threading.Lock()
counter = 0

def safe_count():
    global counter
    for _ in range(100000):
        with lock:
            counter += 1

threads = [threading.Thread(target=safe_count) for _ in range(4)]
for t in threads:
    t.start()
for t in threads:
    t.join()

print(counter)  # 400000

基本选择原则

理解并发编程的基础概念,是掌握更高级异步编程的前提。