一、进程与线程基础
1. 进程(Process)
- 定义:操作系统分配资源(CPU、内存、文件句柄)的基本单位,每个进程有独立的地址空间。
- 特点:独立性:进程间数据隔离,互不影响。通信复杂:需通过IPC(进程间通信)机制(如管道、队列)。创建开销大:适合CPU密集型任务(如计算、批量处理)。
2. 线程(Thread)
- 定义:进程内的执行单元,共享进程的资源(如内存、文件句柄)。
- 特点:轻量级:创建和切换开销小,适合高并发。共享数据:需处理竞态条件(Race Condition)。适合I/O密集型任务(如网络请求、文件读写)。
3. GIL(全局解释器锁)
- 定义:Python解释器为防止多线程同时执行字节码而设置的锁。
- 影响:多线程无法充分利用多核CPU(仅适用于I/O密集型任务)。多进程是CPU密集型任务的解决方案。
二、进程与线程的区别
特性 | 进程 | 线程 |
资源分配 | 独立(CPU、内存) | 共享(同一进程资源) |
通信复杂度 | 需IPC(队列、管道) | 直接共享变量(需锁机制) |
创建开销 | 高(需分配独立资源) | 低(共享进程资源) |
适用场景 | CPU密集型(计算、批量处理) | I/O密集型(网络请求、文件操作) |
三、Python实现进程与线程
1. 多进程(multiprocessing模块)
from multiprocessing import Process
import time
def task(name):
print(f"进程{name}开始")
time.sleep(2)
print(f"进程{name}结束")
if __name__ == "__main__":
processes = []
for i in range(3):
p = Process(target=task, args=(f"P{i}",))
p.start()
processes.append(p)
for p in processes:
p.join() # 等待所有进程完成
2. 多线程(threading模块)
import threading
import time
def task(name):
print(f"线程{name}开始")
time.sleep(2)
print(f"线程{name}结束")
threads = []
for i in range(3):
t = threading.Thread(target=task, args=(f"T{i}",))
t.start()
threads.append(t)
for t in threads:
t.join()
3. 进程池与线程池
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
def heavy_task(n):
return n ** 2
# 进程池(适合CPU密集型)
with ProcessPoolExecutor(max_workers=4) as executor:
results = list(executor.map(heavy_task, range(10)))
# 线程池(适合I/O密集型)
with ThreadPoolExecutor(max_workers=4) as executor:
results = list(executor.map(heavy_task, range(10)))
四、同步与通信机制
1. 线程同步
import threading
counter = 0
lock = threading.Lock()
def increment():
global counter
with lock: # 加锁避免竞态条件
counter += 1
threads = []
for _ in range(10):
t = threading.Thread(target=increment)
t.start()
threads.append(t)
for t in threads:
t.join()
print(f"最终计数:{counter}") # 输出10
2. 进程间通信(IPC)
from multiprocessing import Process, Queue
def producer(q):
q.put("数据来自生产者")
def consumer(q):
data = q.get()
print(f"消费者收到:{data}")
if __name__ == "__main__":
q = Queue()
p = Process(target=producer, args=(q,))
c = Process(target=consumer, args=(q,))
p.start()
c.start()
p.join()
c.join()
五、实战案例:自动化运维中的并发应用
案例1:多线程文件下载
import requests
import threading
def download_file(url, filename):
response = requests.get(url)
with open(filename, "wb") as f:
f.write(response.content)
print(f"下载完成:{filename}")
urls = [
(" https://example.com/file1.zip ", "file1.zip"),
(" https://example.com/file2.zip ", "file2.zip"),
(" https://example.com/file3.zip ", "file3.zip")
]
threads = []
for url, filename in urls:
t = threading.Thread(target=download_file, args=(url, filename))
t.start()
threads.append(t)
for t in threads:
t.join()
案例2:多进程并行处理任务
from multiprocessing import Pool
def process_data(data):
# 模拟耗时操作
return data.upper()
if __name__ == "__main__":
data_list = ["task1", "task2", "task3"]
with Pool(processes=3) as pool:
results = pool.map(process_data, data_list)
print(results) # 输出:['TASK1', 'TASK2', 'TASK3']
六、最佳实践
- I/O密集型任务:优先使用多线程(如网络请求、文件读写)。
- CPU密集型任务:使用多进程(绕过GIL限制)。
- 异步编程:结合asyncio实现非阻塞I/O(适合高并发场景)。
- 资源限制:合理控制并发数量(避免过多进程/线程拖垮系统)。
- 异常处理:确保每个进程/线程能捕获异常,避免静默失败。
七、总结与下一步
- 核心收获:
- 掌握进程与线程的核心区别及适用场景。
- 学会使用multiprocessing和threading模块实现并发。
- 通过实战案例理解并发在自动化运维中的应用。
