网络编程-进程-5、通过多进程实现多任务下载文件

知识点:我们要实现多进程去下载一个文件下的几十个文件,如果按照之前说的有几个任务就创建几个进程,那么我下在几万个文件,那么就要创建几万个进程?显然是不可能的,系统根本承受不了,所以这里要用到进程里面的另外一个方式-进程池。

             进程池:就是创建一个进程池,我把要执行的任务放进进程池,但是进程池存放任务的数量是自己手动设置的,假如一次最多放五个任务,那么这个五个运行完,再放五个进来运行,这样运行的进程数是固定的,能循环运行成千上万个进程任务

 

1、以下载器代码为例,使用到的知识点:进程池,队列:

#!/usr/bin/env python
# coding=utf-8
# author:刘仲
# datetime:2018/7/26 9:23
# software: PyCharm

from multiprocessing import Pool
import multiprocessing
import os,time


def copy_file(q,filename, old_file_name, new_file_name):
    old_file = open(old_file_name+'/' + filename, 'rb')  # 读取原文件里的内容
    data1 = old_file.read()
    old_file.close()
    new_file = open(new_file_name+'/' + filename, 'wb')  # 将原文件的内容写到新文件里
    new_file.write(data1)
    new_file.close()
    time.sleep(0.2)
    q.put(filename)


def main():
    # 用户输入要拷贝的文件夹名字
    old_file_name = input('请输入要拷贝的文件夹名字:')
    # 创建一个新的文件夹
    new_file_name = old_file_name + '[复制]'
    try:
        os.mkdir(new_file_name)
    except:
        print('文件已存在')
    # 创建进程池
    po = Pool(5)
    # 将拷贝文件夹下的文件的任务一个个放到进程池

    q = multiprocessing.Manager().Queue()  # 进程池里创建队列对象要用这种方式,此处采用队列是为了制作下载进度显示
                                            # 保持子进程与主进程之间的通信,为了统计子进程下载一个文件,主进程获取一个来统计下载进度
    list = os.listdir('./test')
    for filename in list:
        po.apply_async(copy_file, args=(q, filename, old_file_name, new_file_name))
    # 关闭进程池
    po.close()
    # 等待子进程结束
    # po.join()
    # 标记初始下载数量
    flag =0
    while True:
        q.get()  # 获取队列里消息
        # print('已下载文件:%s' % num)
        flag += 1
        print('\r下载进度:%.2f' % (flag*100/len(list)),end='')  #  \r回到开始行输出,保证了只显示一个结果
        if flag >= len(os.listdir('./test')):  # 如果下载数量大于或等于原文件中的数量,就退出循环
            break


if __name__ == '__main__':
    main()

运行效果如下:

 

posted @ 2018-07-26 14:15  上海小盖伦  阅读(234)  评论(0编辑  收藏  举报