20、python中的多进程模块multiprocessing与进程池pool_笔记# multiprocessing库的出现很大程度上是为了弥补threading库因为GIL低效的缺陷。# 它完整的复制了一套threading所提供的接口方便迁移。# 唯一的不同就是它使用了多进程而不是多线程。# 每个进程有自己的独立的GIL,完全并行,无GIL的限制(进程中包括线程),# 可充分利用多cpu多核的环境,因此也不会出现进程之间的GIL争抢。# 进程间虽然不能共享某一个内存空间 但是进程间可以通行# python多进程并发,模块名称:multiprocessing# python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程# 借助这个包,可以轻松完成从单进程到多进程并发执行的转换。# multiprocessing包是Python中的多进程管理包。与threading.Thread类似,# 它可以利用multiprocessing.Process对象来创建一个进程。# 该Process对象与Thread对象的用法相同,也有start(), run(), join()等方法。# 此外multiprocessing包中也有Lock/Event/Semaphore/Condition类 (这些对象可以像多线程那样,通过参数传递给各个进程),# 用以同步进程,其用法与threading包中的Thread类一致。# 所以,multiprocessing的很大一部份与threading使用同一套API,只不过换到了多进程的情境。# multiprocessing提供了threading包中没有的IPC(比如Pipe和Queue),效率上更高。# 应优先考虑Pipe和Queue,避免使用Lock/Event/Semaphore/Condition等同步方式 (因为它们占据的不是用户进程的资源,而是线程)。# 同步执行:一个进程在执行任务时,另一个进程必须等待执行完毕,才能继续执行,# 加锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行修改.# 没错,速度是慢了,但牺牲了速度却保证了数据安全。# 异步执行:一个进程在执行任务时,另一个进程无需等待其执行完毕就可以执行,# 当有消息返回时,系统会提醒后者进行处理,这样会很好的提高运行效率# -*- coding: utf-8 -*-__author__ = 'dongfangyao'__date__ = '2018/1/17 下午6:07'__product__ = 'PyCharm'__filename__ = 'processing1'# 多进程import timeimport multiprocessing# 单进程# def work_1(filename, n):# print('work_1 start')# for i in range(n):# with open(filename, 'a') as f_obj:# f_obj.write('i love python \n')# time.sleep(1)# print('work_1 end')### def work_2(filename, n):# print('work_2 start')# for i in range(n):# with open(filename, 'a') as f_obj:# f_obj.write('www.ai111.vip come on! \n')# time.sleep(1)# print('work_2 end')## work_1('dfy.txt', 3)# work_2('dfy.txt', 4)# 多进程# def work_1(filename, n):# print('work_1 start')# for i in range(n):# with open(filename, 'a') as f_obj:# f_obj.write('i love python \n')# time.sleep(1)# print('work_1 end')### def work_2(filename, n):# print('work_2 start')# for i in range(n):# with open(filename, 'a') as f_obj:# f_obj.write('www.ai111.vip come on! \n')# time.sleep(1)# print('work_2 end')## p1 = multiprocessing.Process(target=work_1, args=('dfy.txt', 3))# p2 = multiprocessing.Process(target=work_2, args=('dfy.txt', 4))## p1.start()# p2.start()# 同步执行 异步执行# 加锁 同步def work_1(filename, n, lock): print('work_1 start') lock.acquire() for i in range(n): with open(filename, 'a') as f_obj: f_obj.write('i love python \n') time.sleep(1) print('work_1 end') lock.release()def work_2(filename, n, lock): print('work_2 start') lock.acquire() for i in range(n): with open(filename, 'a') as f_obj: f_obj.write('www.ai111.vip come on! \n') time.sleep(1) print('work_2 end') lock.release()lock = multiprocessing.Lock()p1 = multiprocessing.Process(target=work_1, args=('dfy.txt', 3, lock))p2 = multiprocessing.Process(target=work_2, args=('dfy.txt', 4, lock))p1.start()p2.start()复制代码# pool 进程池# Pool可以提供指定数量的进程,供用户调用,当有新的请求提交到pool中时,# 如果池还没有满,那么就会创建一个新的进程用来执行该请求;# 但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来执行它。# 进程池方法:# apply(func[, args[, kwds]]): 阻塞的执行,比如创建一个有3个线程的线程池,当执行时是创建完一个,执行完函数再创建另一个,变成一个线性的执行. apply_async(func[, args[, kwds[, callback]]]) : 它是非阻塞执行,同时创建3个线程的线城池,同时执行,只要有一个执行完立刻放回池子待下一个执行,并行的执行 .# close(): 关闭pool,使其不在接受新的任务。# terminate() : 结束工作进程,不在处理未完成的任务。# join(): 主进程阻塞,等待子进程的退出, join方法要在close或terminate之后使用。# -*- coding: utf-8 -*-__author__ = 'dongfangyao'__date__ = '2018/1/17 下午6:21'__product__ = 'PyCharm'__filename__ = 'processing2'import osimport multiprocessingimport time# 进程池 pooldef work(n): print('run work(%s) start, work id :%s'%(n, os.getpid())) time.sleep(3) print('work(%s) end, work id :%s'%(n, os.getpid()))print('父进程 id: %s'%os.getpid())# 创建一个进程池 里面同时2个子进程p = multiprocessing.Pool(2)for i in range(5): # 5个任务去提交进程池 # p.apply(work, args=(i, )) p.apply_async(work, args=(i, ))p.close()# p.terminate()p.join()print('父进程结束')复制代码