Python进程详解
前言
在 Python 中,进程是操作系统分配资源和运行程序的基本单位。与线程不同,进程拥有独立的内存空间,并且彼此之间互不干扰,适合处理 CPU 密集型任务。
一、进程与线程的区别
在介绍 Python 进程之前,先了解进程和线程的区别:
-
进程(Process):操作系统分配资源的基本单位,拥有独立的内存空间。多进程可以实现并行计算,适合 CPU 密集型任务。
-
线程(Thread):线程是程序执行的最小单位,多个线程共享进程的内存空间。适合 IO 密集型任务。
-
区别
- 进程切换开销大,线程切换开销小。
- 进程之间相互独立,线程共享内存。
- 多进程更适合并行计算,多线程适合 IO 密集型任务。
二、multiprocessing 模块概述
multiprocessing 是 Python 标准库中用于实现多进程编程的模块,提供了与 threading 模块类似的接口,但是真正实现了并行计算。它绕过了 Python 的 GIL(Global Interpreter Lock),支持多核 CPU 并行执行任务。
三、创建进程
1. 使用 Process 类创建进程
from multiprocessing import Process
import os
# 子进程执行的函数
def run_process(name):
print(f'子进程 {name} 启动,进程ID:{os.getpid()}')
if __name__ == '__main__':
print(f'父进程ID:{os.getpid()}')
# 创建进程
p = Process(target=run_process, args=('test',))
p.start() # 启动进程
p.join() # 等待进程结束
print('子进程执行完成')
✅ 代码解析:
Process(target=run_process, args=('test',)):创建子进程,目标函数为run_process。p.start():启动进程。p.join():等待子进程执行完毕后再执行后续代码。
四、进程间通信(IPC)
Python 提供了多种方式进行进程间通信,如:
Queue:队列通信Pipe:管道通信Manager:共享内存
1. 使用 Queue 实现进程通信
from multiprocessing import Process, Queue
import time
def producer(q):
"""生产者进程"""
for i in range(5):
print(f'生产者生产:{i}')
q.put(i)
time.sleep(0.5)
def consumer(q):
"""消费者进程"""
while not q.empty():
item = q.get()
print(f'消费者消费:{item}')
time.sleep(1)
if __name__ == '__main__':
q = Queue()
p1 = Process(target=producer, args=(q,))
p2 = Process(target=consumer, args=(q,))
p1.start()
p1.join()
p2.start()
p2.join()
✅ 代码解析:
Queue():创建进程安全的队列。q.put(i):将数据放入队列。q.get():从队列取出数据。
五、进程池(Pool)
当需要同时运行大量进程时,可以使用 Pool 对进程进行管理。进程池可以限制并发进程的数量,并自动管理任务分配。
1. 使用进程池处理任务
from multiprocessing import Pool
import os
import time
def task(n):
print(f'子进程 {os.getpid()} 执行任务 {n}')
time.sleep(1)
return n ** 2
if __name__ == '__main__':
with Pool(4) as pool: # 创建进程池,最大并发数为4
results = pool.map(task, range(8))
print(f'结果:{results}')
✅ 代码解析:
Pool(4):创建包含 4 个进程的进程池。pool.map(task, range(8)):将任务分配给进程池中的进程执行。- 返回值为任务的执行结果。
六、进程同步
在多进程环境下,多个进程可能会同时访问共享资源,导致数据不一致。为防止这种情况,可以使用 Lock 进行同步。
1. 使用锁实现同步
from multiprocessing import Process, Lock
import time
def task(lock, n):
lock.acquire() # 加锁
print(f'进程 {n} 获取锁')
time.sleep(1)
print(f'进程 {n} 释放锁')
lock.release() # 释放锁
if __name__ == '__main__':
lock = Lock()
processes = []
for i in range(4):
p = Process(target=task, args=(lock, i))
processes.append(p)
p.start()
for p in processes:
p.join()
✅ 代码解析:
lock.acquire():获取锁。lock.release():释放锁。- 多个进程在访问共享资源时,使用锁确保互斥访问,防止数据冲突。
七、Manager 实现共享变量
multiprocessing.Manager 提供了一种方式,可以在进程间共享数据,如列表、字典等。
1. 使用 Manager 共享数据
from multiprocessing import Process, Manager
def worker(shared_list, value):
shared_list.append(value)
print(f'进程 {value} 添加 {value} 到列表')
if __name__ == '__main__':
manager = Manager()
shared_list = manager.list()
processes = []
for i in range(5):
p = Process(target=worker, args=(shared_list, i))
processes.append(p)
p.start()
for p in processes:
p.join()
print(f'最终列表:{shared_list}')
✅ 代码解析:
manager.list():创建进程间共享的列表。- 子进程向共享列表中添加数据,主进程读取最终结果。
八、multiprocessing 与 concurrent.futures
Python3.2 引入了 concurrent.futures 模块,该模块提供了更简洁的接口来进行并行计算。与 multiprocessing 相比,concurrent.futures 的 ProcessPoolExecutor 更易于使用。
1. 使用 ProcessPoolExecutor
from concurrent.futures import ProcessPoolExecutor
import os
def task(n):
print(f'进程 {os.getpid()} 执行任务 {n}')
return n * n
if __name__ == '__main__':
with ProcessPoolExecutor(max_workers=4) as executor:
results = list(executor.map(task, range(8)))
print(f'结果:{results}')
✅ 代码解析:
ProcessPoolExecutor(max_workers=4):创建进程池。executor.map():将任务分配给多个进程并行执行。
总结
本文介绍了 Python 中的进程模型,包括:
- 使用
multiprocessing模块创建进程。 - 进程间通信(IPC)。
- 使用进程池处理并行任务。
- 进程同步与共享变量。
- 使用
concurrent.futures模块简化并行计算。
✅ 多进程编程适合处理 CPU 密集型任务,可以充分利用多核 CPU 性能,提高程序效率。
2356

被折叠的 条评论
为什么被折叠?



