多进程编程是一种并发编程的方式,通过使用多个进程来提高程序的并发性能。与多线程相比,多进程编程在处理CPU密集型任务时更有效,因为每个进程都有独立的内存空间和全局解释器锁(GIL)。
1. 什么是多进程
多进程是一种并发编程模型,通过创建多个独立的进程来执行任务。每个进程都有自己的内存空间,相互之间不共享数据,因此多进程编程在处理并行计算和避免GIL限制方面具有优势。
2. 创建进程
在Python中,可以使用multiprocessing
模块来创建和管理进程。创建进程的基本步骤如下:
- 创建一个
multiprocessing.Process
对象,并指定目标函数。 - 调用
start
方法启动进程。 - 调用
join
方法等待进程结束。
示例
import multiprocessing
import time
def worker(name):
print(f"进程 {name} 开始")
time.sleep(2)
print(f"进程 {name} 结束")
# 创建并启动进程
process1 = multiprocessing.Process(target=worker, args=("Process-1",))
process2 = multiprocessing.Process(target=worker, args=("Process-2",))
process1.start()
process2.start()
process1.join()
process2.join()
print("主进程结束")
3. 使用进程池
使用multiprocessing.Pool
可以方便地管理多个进程。它提供了一个高级接口,用于创建和管理进程池。
示例
from multiprocessing import Pool
import time
def task(name):
print(f"任务 {name} 开始")
time.sleep(2)
print(f"任务 {name} 结束")
# 创建进程池
with Pool(3) as pool:
pool.apply_async(task, ("Task-1",))
pool.apply_async(task, ("Task-2",))
pool.apply_async(task, ("Task-3",))
pool.close()
pool.join()
print("主进程结束")
4. 进程间通信
进程间可以通过队列(Queue)和管道(Pipe)进行通信。multiprocessing.Queue
和multiprocessing.Pipe
是线程安全的,可以用于在进程之间传递数据。
示例:使用队列进行进程间通信
import multiprocessing
import time
def producer(q):
for i in range(5):
print(f"生产者生产数据: {i}")
q.put(i)
time.sleep(1)
def consumer(q):
while True:
item = q.get()
if item is None:
break
print(f"消费者消费数据: {item}")
time.sleep(2)
# 创建队列
q = multiprocessing.Queue()
# 创建并启动进程
producer_process = multiprocessing.Process(target=producer, args=(q,))
consumer_process = multiprocessing.Process(target=consumer, args=(q,))
producer_process.start()
consumer_process.start()
producer_process.join()
# 向队列发送结束信号
q.put(None)
consumer_process.join()
print("主进程结束")
5. 进程同步
进程间同步可以使用multiprocessing.Lock
、multiprocessing.Semaphore
等同步原语来实现,确保多个进程对共享资源的安全访问。
示例
import multiprocessing
# 共享资源
counter = multiprocessing.Value('i', 0)
lock = multiprocessing.Lock()
def increment_counter(lock, counter):
for _ in range(100000):
with lock:
counter.value += 1
# 创建并启动进程
process1 = multiprocessing.Process(target=increment_counter, args=(lock, counter))
process2 = multiprocessing.Process(target=increment_counter, args=(lock, counter))
process1.start()
process2.start()
process1.join()
process2.join()
print(f"最终计数值: {counter.value}")
6. 可运行的Python案例
下面是一个完整的Python程序,演示了多进程编程的基本操作,包括创建进程、使用进程池、进程间通信和进程同步。
import multiprocessing
import time
from multiprocessing import Pool
# 示例1:创建进程
def worker(name):
print(f"进程 {name} 开始")
time.sleep(2)
print(f"进程 {name} 结束")
process1 = multiprocessing.Process(target=worker, args=("Process-1",))
process2 = multiprocessing.Process(target=worker, args=("Process-2",))
process1.start()
process2.start()
process1.join()
process2.join()
print("主进程结束")
# 示例2:使用进程池
def task(name):
print(f"任务 {name} 开始")
time.sleep(2)
print(f"任务 {name} 结束")
with Pool(3) as pool:
pool.apply_async(task, ("Task-1",))
pool.apply_async(task, ("Task-2",))
pool.apply_async(task, ("Task-3",))
pool.close()
pool.join()
print("主进程结束")
# 示例3:进程间通信
def producer(q):
for i in range(5):
print(f"生产者生产数据: {i}")
q.put(i)
time.sleep(1)
def consumer(q):
while True:
item = q.get()
if item is None:
break
print(f"消费者消费数据: {item}")
time.sleep(2)
q = multiprocessing.Queue()
producer_process = multiprocessing.Process(target=producer, args=(q,))
consumer_process = multiprocessing.Process(target=consumer, args=(q,))
producer_process.start()
consumer_process.start()
producer_process.join()
q.put(None)
consumer_process.join()
print("主进程结束")
# 示例4:进程同步
counter = multiprocessing.Value('i', 0)
lock = multiprocessing.Lock()
def increment_counter(lock, counter):
for _ in range(100000):
with lock:
counter.value += 1
process1 = multiprocessing.Process(target=increment_counter, args=(lock, counter))
process2 = multiprocessing.Process(target=increment_counter, args=(lock, counter))
process1.start()
process2.start()
process1.join()
process2.join()
print(f"最终计数值: {counter.value}")