python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。Python提供了非常好用的多进程包multiprocessing,只需要定义一个函数,Python会完成其他所有事情。借助这个包,可以轻松完成从单进程到并发执行的转换。multiprocessing支持子进程、通信和共享数据、执行不同形式的同步,提供了Process、Queue、Pipe、Lock等组件
一、使用多进程
进程也有两种调用方式、直接调用和继承式调用。


import multiprocessing,time def hello(i): print("start...",i) time.sleep(3) print("end...",i) if __name__ == "__main__": for i in range(3): p = multiprocessing.Process(target=hello,args=(i,)) p.start()


import multiprocessing import time class My_Process(multiprocessing.Process): def __init__(self, i): multiprocessing.Process.__init__(self) self.i = i def run(self): print("start...",self.i) time.sleep(3) print("end...",self.i) if __name__ == '__main__': for i in range(3): p = My_Process(i) p.start()
与线程的使用方法类似,只是将threading.Thread换成了进程的multiprocessing.Process
p.deamon ------> 线程的setDeamon方法
p.join ------> 线程的join方法
二、Lock、RLock
声明方式:lock = multiprocessing.Lock(),其余同多线程
三、Semaphore
声明方式:s = multiprocessing.Semaphore(),其余同多线程
四、event
声明方式:e = multiprocessing.Event(),其余同多线程
五、Queue


import multiprocessing import time def f(q): q.put([42, None, 'hello']) if __name__ == '__main__': q = multiprocessing.Queue() p = multiprocessing.Process(target=f, args=(q,)) p.start() print(q.get()) # prints "[42, None, 'hello']" p.join()
六、Pipe


import multiprocessing import time def proc1(pipe): while True: for i in range(10000): print("send: %s" %(i)) pipe.send(i) time.sleep(0.5) def proc2(pipe): while True: print("proc2 rev:", pipe.recv()) time.sleep(1) def proc3(pipe): while True: print("proc3 rev:", pipe.recv()) time.sleep(1) if __name__ == "__main__": pipe = multiprocessing.Pipe() p1 = multiprocessing.Process(target=proc1, args=(pipe[0],)) p2 = multiprocessing.Process(target=proc2, args=(pipe[1],)) p3 = multiprocessing.Process(target=proc3, args=(pipe[1],)) p1.start() p2.start() p3.start() p1.join() p2.join() p3.join()
七、Pool
Pool可以提供指定数量的进程,供用户调用,当有新的请求提交到pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来它。
- apply_async它是非阻塞,apply是阻塞的(主进程会被阻塞直到函数执行结束,不建议使用)
- close() 关闭pool,使其不在接受新的任务。
- terminate() 结束工作进程,不在处理未完成的任务。
- join() 主进程阻塞,等待子进程的退出, join方法要在close或terminate之后使用。


import multiprocessing import time def func(msg): print("msg:", msg) time.sleep(3) print("end") if __name__ == "__main__": pool = multiprocessing.Pool(processes = 3) for i in range(5): msg = "hello %d" %(i) pool.apply_async(func, (msg, )) #维持执行的进程总数为processes,当一个进程执行完毕后会添加新的进程进去 print("Mark~ Mark~ Mark~~~~~~~~~~~~~~~~~~~~~~") pool.close() pool.join() #调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束 print("Sub-process(es) done.") >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> #输出结果: Mark~ Mark~ Mark~~~~~~~~~~~~~~~~~~~~~~ msg: hello 0 msg: hello 1 msg: hello 2 end msg: hello 3 end msg: hello 4 end end end Sub-process(es) done.


import multiprocessing import time def func(msg): print("msg:", msg) time.sleep(3) print("end") if __name__ == "__main__": pool = multiprocessing.Pool(processes = 3) for i in range(5): msg = "hello %d" %(i) pool.apply(func, (msg, )) #维持执行的进程总数为processes,当一个进程执行完毕后会添加新的进程进去 print("Mark~ Mark~ Mark~~~~~~~~~~~~~~~~~~~~~~") pool.close() pool.join() #调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束 print("Sub-process(es) done.") >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> #输出结果: msg: hello 0 end msg: hello 1 end msg: hello 2 end msg: hello 3 end msg: hello 4 end Mark~ Mark~ Mark~~~~~~~~~~~~~~~~~~~~~~ Sub-process(es) done.