class multiprocessing.Process(group = None,target = None,name = None,args =(),kwargs = {},*,daemon = None )
Process 创建进程
from multiprocessing import Process
import os
def info(title):
print(title)
print('module name:', __name__)
print('parent process:', os.getppid())
print('process id:', os.getpid())
def f(name):
info('function f')
print('hello', name)
if __name__ == '__main__':
info('main line')
p = Process(target=f, args=('bob',))
p.start()
p.join()
进程间通讯
使用queue和pipe进行进程通讯,可以避免使用锁,是进程和线程安全的
队列queue
from multiprocessing import Process, Queue
def f(q):
q.put([42, None, 'hello'])
if __name__ == '__main__':
q = Queue()
p = Process(target=f, args=(q,))
p.start()
print(q.get()) # prints "[42, None, 'hello']"
p.join()
管道Pipe
该Pipe()函数返回一对由管道连接的连接对象,默认情况下为双工(双向)。例如:
from multiprocessing import Process, Pipe
def f(conn):
conn.send([42, None, 'hello'])
conn.close()
if __name__ == '__main__':
parent_conn, child_conn = Pipe()
p = Process(target=f, args=(child_conn,))
p.start()
print(parent_conn.recv()) # prints "[42, None, 'hello']"
p.join()
进程之间的同步
通过Lock类实现,数据通过锁进行同步
from multiprocessing import Process, Lock
def f(l, i):
l.acquire() #获得锁
try:
print('hello world', i)
finally:
l.release() #释放锁
if __name__ == '__main__':
lock = Lock()
for num in range(10):
p = Process(target=f, args=(lock, num))
p.start()
进程之间共享状态
在进行并发编程时,通常最好尽可能避免使用共享状态。使用多个进程时尤其如此。
但是,如果您确实需要使用某些共享数据,则 multiprocessing可以提供一些方法。
共享内存
数据可以使用Value或 存储在共享内存映射中Array。例如,下面的代码
from multiprocessing import Process, Value, Array
def f(n, a):
# n=num;a = arr
n.value = 3.1415927
for i in range(len(a)):
a[i] = -a[i]
if __name__ == '__main__':
num = Value('d', 0.0) #浮点型数据num
arr = Array('i', range(10)) #有符号整形数据
p = Process(target=f, args=(num, arr))
p.start()
p.join()
print(num.value)
print(arr[:])
创建num和arr时,'d'与'i'参数用于被array模块使用的类型标志 :'d'表示一个双精度浮点数,'i'表示有符号整数。这些共享对象将是进程和线程安全的。
为了更灵活地使用共享内存,可以使用multiprocessing.sharedctypes支持创建从共享内存分配的任意ctypes对象的 模块。
服务器进程
from multiprocessing import Process, Manager
def f(d, l):
d[1] = '1' #字典赋值
d['2'] = 2
d[0.25] = None
l.reverse() #list的值反向
if __name__ == '__main__':
with Manager() as manager: #等价于manager = Manager()
d = manager.dict()
l = manager.list(range(10))
p = Process(target=f, args=(d, l))
p.start()
p.join()
print(d)
print(l)