多进程Multiprocessing
multiprocessing是python的多进程管理包,和threading.Thread类似。
下面是一个简单的多进程例子:
from multiprocessing import Process import time def f(name): time.sleep(2) print('hello', name) if __name__ == '__main__': p = Process(target=f, args=('bob',)) p.start() p.join()
为了更加清楚地了解多进程之间的关系,将进程ID号打印出来:
# _*_coding:utf-8_*_ 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()) print(" ") def f(name): info(' 33[31;1mfunction f 33[0m') print('hello', name) if __name__ == '__main__': info(' 33[32;1mmain process line 33[0m') p = Process(target=f, args=('bob',)) p.start() p.join()
进程间通信
不同进程间内存是不共享的,要想实现两个进程间的数据交换,可以用以下方法:
Queues
使用方法跟threading里的queue差不多。
# _*_coding:utf-8_*_ 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()) # "[42, None, 'hello']" # 从队列q中获取数据 p.join()
Pipes管道
# _*_coding:utf-8_*_ from multiprocessing import Process, Queue, 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()
Managers
# _*_coding:utf-8_*_ from multiprocessing import Process, Queue, Pipe, Manager def f(d, l): d[1] = '1' d['2'] = 2 d[0.25] = None l.append(1) print(l) if __name__ == '__main__': with Manager() as manager: d = manager.dict() l = manager.list(range(5)) p_list = [] for i in range(10): p = Process(target=f, args=(d, l)) p.start() p_list.append(p) for res in p_list: res.join() print(d) print(l)
进程同步
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): Process(target=f, args=(lock, num)).start()
进程池
进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进程,那么程序就会等待,直到进程池中有可用进程为止。
进程池中有两个方法:
- apply
- apply_async
# _*_coding:utf-8_*_ from multiprocessing import Process, Pool, freeze_support import time def Foo(i): time.sleep(2) return i + 100 def Bar(arg): print('-->exec done:', arg) if __name__ == '__main__': freeze_support() pool = Pool(5) # 创建5个线程池 for i in range(10): pool.apply_async(func=Foo, args=(i,), callback=Bar) # pool.apply(func=Foo, args=(i,)) print('end') pool.close() # 关闭pool,使其不在接受新的任务。 pool.join() # 进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。 # 主进程阻塞,等待子进程的退出, join方法要在close或terminate之后使用。