1,进程池
当需要创建的子进程数量不多时,可以直接利用multiprocessing中的Process动态生成多个进程,但如果是上百或者上千个目标,手动的动态创建进程工作量大,此时可以用到multiprocessing中的Pool方法。
初始化Pool时,可以指定一个量大的进程数,当有新的请求交到Pool中时,如果池还没有满,那么就会创建一个新的进程用来执行请求,,但如果池中的进程数已经达到指定的最大值,那么该请求就会待定,直到池中有经常结束,才会用之前的进程来执行新的任务。
apply_async 使用非阻塞的方式调用函数,并行。
apply 使用阻塞的方式调用函数
阻塞方式必须等待上一个进程退出之后菜鸟执行下一个进程
并发:交替去做
并行:同时去做
1,进程池的创建
from multiprocessing import Pool
import random
import time
import os
def work(times):
print('这是第{}次的任务,有进程编号{}的进程来完成'.format(times, os.getpid()))
if __name__ == '__main__':
pool = Pool(3) # 定义一个进程池,最大进程数为3
# 十个任务三条进程怎么完成
for i in range(0, 10):
pool.apply_async(work, args=(i,))
pool.close() # 关闭池子,不让再进新的需求
pool.join() #一定要放在close后面
这是第0次的任务,有进程编号6996的进程来完成
这是第1次的任务,有进程编号6996的进程来完成
这是第2次的任务,有进程编号6996的进程来完成
这是第3次的任务,有进程编号6996的进程来完成
这是第4次的任务,有进程编号6996的进程来完成
这是第5次的任务,有进程编号6996的进程来完成
这是第6次的任务,有进程编号6996的进程来完成
这是第7次的任务,有进程编号6996的进程来完成
这是第8次的任务,有进程编号6996的进程来完成
这是第9次的任务,有进程编号6996的进程来完成
join : 指的是所有的子进程完成主进程才结束
2,进程池通信
from multiprocessing import Pool,Manager
import time
import os
def read(que):
print('进程启动,当前的id时{},父进程id是{}'.format(os.getpid(),os.getpid()))
for i in range(10):
print('获取到的数据是{}'.format(os.getpid()))
def write(que):
print('进程启动,当前的id时{},父进程id是{}'.format(os.getpid(),os.getpid()))
for i in range(10):
que.put('数字')
if __name__=='__main__':
print('这是主进程的id是{}'.format(os.getpid()))
#创建一个进程池
pool=Pool()
#创建一个队列
q=Manager().Queue()
print(q)
#运行进程池中的进程
pool.apply_async(write,args=(q,))
time.sleep(1)#保证写完再读
pool.apply_async(read,args=(q,))
#先关闭进程池
pool.close()
#进行保护
pool.join()
print('这是结束,主进程id是{}'.format(os.getpid()))#os.gtepid()获取id
2,进程的应用
应用:文件夹copy器(多进程版)
import multiprocessing
import os,time,random
def copy_file(queue,file_name,source_folder_name,dest_filder_name):
'''copy文件指定的路径'''
f_read=open(source_folder_name+"/"+file_name,'rb')
f_write=open(dest_filder_name+"/"+file_name,'wb')
while True:
time.sleep(random.random())
content=f_read.read(1024)
if content:
f_write.write(content)
else:
break
f_read.close()
f_write.close()
#发送已经拷贝完毕的文件名字
queue.put(file_name)
def main():
#获取要复制的文件夹
source_folder_name-input('请输入要复制的文件名字:')
#整理目标文件夹
dest_folder_name=source_folder_name+" "