1. Multiprocessing模块简介
Python 3.x中的
1.1 进程与线程的区别
在并行编程中,针对可并行的任务,我们一般是通过进程或者线程的方式来实现多任务的并行执行。进程与线程的主要区别如下:
进程拥有独立的内存空间,每个进程之间相互独立,互不影响;而线程共享其所在进程的内存空间
每个进程由自己的程序代码、数据集、堆栈和其他系统资源组成;线程通常被定义为进程中的轻量级实体,它们共享进程的上下文,并可使用该上下文中的共享数据及共享句柄等
在进程间通信时,需要使用操作系统提供的IPC(Interprocess Communication)机制,如管道、队列、共享内存等;在同一个进程内的线程间通信,可直接共享变量和对象,或者使用Python提供的线程同步机制,如锁、信号量等
进程的创建、销毁、切换等操作,需要操作系统提供帮助,代价较大;线程的创建、销毁、切换等操作较为轻量级
1.2 Multiprocessing模块的基本介绍
import multiprocessing
def my_function(num):
print(f"Process {num} started")
if __name__ == '__main__':
p1 = multiprocessing.Process(target=my_function, args=(1,))
p2 = multiprocessing.Process(target=my_function, args=(2,))
p1.start()
p2.start()
p1.join()
p2.join()
上述代码创建了两个新的进程,它们分别执行了
2. 进程间通信
在多进程编程中,常常需要进行进程间通信,以实现数据共享或者协调进程之间的行为。Python中的
2.1 队列(Queue)
队列是一种常用的线程同步工具,可用于进程之间的通信。
from multiprocessing import Process, Queue
def worker(q):
while True:
item = q.get()
if item is None:
break
print(item)
if __name__ == "__main__":
q = Queue()
p1 = Process(target=worker, args=(q,))
p2 = Process(target=worker, args=(q,))
p1.start(); p2.start()
for i in range(10):
q.put(i)
q.put(None)
q.put(None)
p1.join(); p2.join()
上述代码中,首先创建了一个,并创建了两个进程
中读取数据进行处理。主进程将数据放入队列
中,并向队列中添加两个
2.2 管道(Pipe)
管道是一种常用的进程间通信方式,可实现双向数据传输。管道由队列构成,允许多个进程同时对管道进行读写操作。Python中的
from multiprocessing import Process, Pipe
def writer(conn, msg):
conn.send(msg)
conn.close()
if __name__ == '__main__':
parent_conn, child_conn = Pipe()
p = Process(target=writer, args=(child_conn, 'Hello, World!'))
p.start()
print(parent_conn.recv())
p.join()
上述代码中,首先创建了一个管道
2.3 共享内存(Value、Array)
共享内存是一种高效的进程间通信方式,可以不涉及操作系统调用,直接将一段内存区域映射到多个进程的地址空间中,从而完成数据共享。
from multiprocessing import Process, Value, Array
def f(n, a):
n.value = 3.1415926
for i in range(len(a)):
a[i] *= i
if __name__ == '__main__':
num = Value('d', 0.0)
arr = Array('i', range(10))
p = Process(target=f, args=(num, arr))
p.start()
p.join()
print(num.value)
print(arr[:])
上述代码中,首先创建了一个