RUN__IT # 多任务创建进程池实现文件夹递归copy

进程

进程的创建步骤

# 导入进程模块
import multiprocessing
# 创建一个进程的实例对象
p = multiprocessing.Process(target=fun_name,args=(元组),kwargs={字典})
# 创建并启动进程
p.start()
​
p.join()  可以阻塞主进程,等待子进程的结束
​
# 获取进程的pid
os.getpid()
# 获取进程的父进程的pid
os.getppid()
​
**进程中,主进程的父进程pid是系统产生的,子进程的父进程pid是主进程的pid,
主进程死掉,子进程不会死,子进程会有新的父进程,(这个进程的名字好像是upstart)如果继续kill掉这个进程,将锁屏。

通过Queue实现进程间通信

# 创建一个队列
q = multiprocessing.Queue(5)  # 5代表队列可以接受的容量
# 向队列添加数据
q.put(data)
# 从队列中获取数据
q.get()
# 判断队列是否为空,为空返回True
q.empty()
# 判断队列中是否已满
q.full()
​
**注意:如果是通过进程池创建的进程,那么队列的使用要用 multiprocessing.Manager().Queue()的方式,否则会报错。

进程池Pool

# 导入进程池模块
from multiprocessing import Pool
# 定义进程池,最大进程数
po = Pool(3)
# 通过进程池调用目标 apply_async 非阻塞,不会等待子进程结束,apply 阻塞,会等待子进程结束才结束
po.apply_async(要调用的目标,(传递给目标的参数元组,))
# 关闭进程池
po.close()
# 等待进程池执行完毕
po.join()

案例

多任务通过进程池,实现目录中文件copy,若有子目录就进行递归copy

import multiprocessing
import os
import time


def copy(q, file_name, old_folder_name, new_folder_name):
    """复制文件"""
    # 判断copy的是文件夹
    if os.path.isdir(old_folder_name + "/" + file_name):
        # 创建文件夹
        try:
            os.mkdir(new_folder_name + "/" + file_name)
        except:
            pass
        # 获取其中的内容
        son_file_names = os.listdir(old_folder_name + "/" + file_name)
        # 遍历获取内容,递归copy
        for son_file_name in son_file_names:
            copy(q, son_file_name, old_folder_name + "/" + file_name, new_folder_name + "/" + file_name)

    else:
        # 打开要复制的文件夹
        with open(old_folder_name + "/" + file_name, "rb") as f:
            msg = f.read()

        # 写入文件
        with open(new_folder_name + "/" + file_name, "wb") as f:
            f.write(msg)
        q.put(file_name)
        time.sleep(0.01)


def conut_file(old_folder_name):
	"""通过递归统计文件个数"""
    file_names = os.listdir(old_folder_name)
    for file_name in file_names:
        # 如果是文件夹就递归打开计数
        if os.path.isdir(old_folder_name + "/" + file_name):
            conut_file(old_folder_name + "/" + file_name)
        else:
            global file_names_num
            file_names_num += 1


file_names_num = 0


def main():
    """多任务进程池复制文件"""
    # 输入要复制的文件夹名
    old_folder_name = input("输入要复制的文件夹\n")
    # 新的文件夹名字
    new_folder_name = old_folder_name + "[复件]"
    # 创建新文件夹
    try:
        os.mkdir(new_folder_name)
    except:
        pass
    # 递归统计文件个数
    conut_file(old_folder_name)
    # 获取文件夹中的内容
    file_names = os.listdir(old_folder_name)
    # 创建进程池
    po = multiprocessing.Pool(5)
    # 创建一个队列
    q = multiprocessing.Manager().Queue()
    for file_name in file_names:
        po.apply_async(copy, args=(q, file_name, old_folder_name, new_folder_name))
    # 关闭进程池
    po.close()
    # 显示copy进度
    copy_ok = 0
    while True:
        # 获取一个队列中的内容
        q.get()
        copy_ok += 1
        # 显示进度
        print("\r copy已完成:%.2f%%" % (copy_ok * 100 / file_names_num), end="")
        if copy_ok >= file_names_num:
            break


if __name__ == '__main__':
    main()

对上面代码中文件统计个数部分的改进版

import multiprocessing
import os
import time


def copy(q, file_name, old_folder_name, new_folder_name):
    """复制文件"""
    # 判断copy的是文件夹
    if os.path.isdir(old_folder_name + "/" + file_name):
        # 创建文件夹
        try:
            os.mkdir(new_folder_name + "/" + file_name)
        except:
            pass
        # 获取其中的内容
        son_file_names = os.listdir(old_folder_name + "/" + file_name)
        # 遍历获取内容,递归copy
        for son_file_name in son_file_names:
            copy(q, son_file_name, old_folder_name + "/" + file_name, new_folder_name + "/" + file_name)

    else:
        # 打开要复制的文件夹
        with open(old_folder_name + "/" + file_name, "rb") as f:
            msg = f.read()

        # 写入文件
        with open(new_folder_name + "/" + file_name, "wb") as f:
            f.write(msg)
        q.put(file_name)
        time.sleep(0.01)


def main():
    """多任务进程池复制文件"""
    # 输入要复制的文件夹名
    old_folder_name = input("输入要复制的文件夹\n")
    # 新的文件夹名字
    new_folder_name = old_folder_name + "[复件]"
    # 创建新文件夹
    try:
        os.mkdir(new_folder_name)
    except:
        pass
    # 统计文件个数
    for dirpath, dirnames, file_names in os.walk(old_folder_name):
        file_names_num = len(file_names)

    # 获取文件夹中的内容
    file_names = os.listdir(old_folder_name)
    # 创建进程池
    po = multiprocessing.Pool(5)
    # 创建一个队列
    q = multiprocessing.Manager().Queue()
    for file_name in file_names:
        po.apply_async(copy, args=(q, file_name, old_folder_name, new_folder_name))
    # 关闭进程池
    po.close()
    # 显示copy进度
    copy_ok = 0
    while True:
        # 获取一个队列中的内容
        q.get()
        copy_ok += 1
        # 显示进度
        print("\r copy已完成:%.2f%%" % (copy_ok * 100 / file_names_num), end="")
        if copy_ok >= file_names_num:
            break


if __name__ == '__main__':
    main()

猜你喜欢

转载自blog.csdn.net/RUN__IT/article/details/89225587
今日推荐