Python3中的multiprocessing模块是一个与threading模块类似,提供生成进程的API
多进程multiprocessing模块允许程序员充分利用给定机器上的多个CPU(处理器),但注意CPU是不认识进程的,进程更像是一个线程的容器,这也是为啥一个进程至少包含一个线程,但进程有两个缺点:
1.进程在同一时间只能干一件事,如果想同时干两件事或以上,进程就心有余而力不足了
2.进程在执行过程中如果被阻塞,比如等待输入,整个进程就会被挂起,无法做后面的操作
import os import multiprocessing as mp def process_func(name): print("进程ID,%s" % os.getpid()) print("父进程ID,%s" % os.getppid()) print("Hello,%s" % name) print("--------------------------") if __name__ == "__main__": p = mp.Process(target=process_func, args=("Jet", )) # 创建进程1 p2 = mp.Process(target=process_func, args=("Jack",)) # 创建进程2 p.start() # 启动进程1 p2.start() # 启动进程2
进程间的数据交互
不同进程的内存都是独享的,所以要想实现不同进程间的数据交互,主要有两种方式:
1.使用multiprocessing.Queue队列,特点是:FIFO(先进先出)同时它也是线程安全的
import multiprocessing as mp """ Queue进程间的互相通讯 特点: FIFO(先进先出) 线程安全 """ def process_func(q): print("Hello,%s" % q.get()) # 取数据 print("Hello,%s" % q.get()) print("Hello,%s" % q.get()) if __name__ == "__main__": que = mp.Queue() que.put("Jet is 1") # 存数据 que.put("Jack is 2") que.put("Judy is 3") p = mp.Process(target=process_func, args=(que, )) # 创建进程 p.start() # 启动进程
2.使用multiprocessing.Pipe()管道函数,获取两个连接对象来进程通讯,特点是:双向收发
import multiprocessing as mp """ Pipes进程间的互相通讯 特点: 利用两个连接对象进行收发通讯 """ def process_func(conn): print("Hello,%s" % conn.recv()) # 接收数据 print("Hello,%s" % conn.recv()) print("Hello,%s" % conn.recv()) conn.send("你好") # 发送数据 conn.close() if __name__ == "__main__": front_conn, behind_conn = mp.Pipe() front_conn.send("Jet is 1") # 发送数据 front_conn.send("Jack is 2") front_conn.send("Judy is 3") p = mp.Process(target=process_func, args=(behind_conn, )) # 创建进程 p.start() # 启动进程 p.join() print(front_conn.recv()) # 接收数据 front_conn.close()
进程间的数据共享
能不能让不同的进程之间共享一份数据呢,答案是肯定的,不过就要使用Manager对象了,而且Manager是线程安全的
import multiprocessing as mp """ Manager进程间的数据共享 特点: 多个进程之间共享一些数据 """ def process_func(d, name ): d[name] = name if __name__ == "__main__": with mp.Manager() as mgr: dt = mgr.dict() p = mp.Process(target=process_func, args=(dt, "Jet")) # 创建进程 p1 = mp.Process(target=process_func, args=(dt, "Jack")) # 创建进程 p1.start() p.start() # 启动进程 p.join() p1.join() print(dt)
进程同步
如果多个进程的目标为同一个对象时,比如多个进程都要向屏幕输出,那么此时,就要让这些进程变成串行的,怎么办?加锁!
import os import time import multiprocessing as mp def process_func(l, name): try: l.acquire() print("进程ID,%s" % os.getpid()) print("父进程ID,%s" % os.getppid()) print("Hello,%s" % name) print("--------------------------") time.sleep(2) finally: l.release() if __name__ == "__main__": lock = mp.Lock() p = mp.Process(target=process_func, args=(lock, "Jet", )) # 创建进程1 p2 = mp.Process(target=process_func, args=(lock, "Jack",)) # 创建进程2 p.start() # 启动进程1 p2.start() # 启动进程2
进程池
进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止
from multiprocessing import Process, Pool import time def process_func(i): time.sleep(1) print(i) return i + 100 def callback_func(arg): print('-->exec done:', arg) if __name__ == "__main__": pool = Pool(3) for i in range(10): pool.apply_async(func=process_func, args=(i,), callback=callback_func) # 异步调用 # pool.apply(func=Foo, args=(i,)) # 同步调用 print('end') pool.close() pool.join() # 进程池中的进程执行玩在关闭,先close()在 join()
参考资料
http://www.cnblogs.com/alex3714/articles/5230609.html
http://python.usyiyi.cn/translate/python_352/library/multiprocessing.html