今日内容概述:
多进程实现文件夹下载、迭代器、生成器、协程
昨日回顾
程序:一个静态的概念
进程:一个动态的概念,就是程序运行起来的状态,用于一定的资源
线程:运行在进程之内,依赖于进程,
进程和线程区别:
共同点:都可以完成多任务区别: 线程: threading 依赖于进程 多线程之间共享全局的变量 主线程等待子线程结束,才结束 系统开销较小 进程: multiprocessing 运行起来的应用程序,占有一些资源 写时拷贝,进程不共享全局的资源 通过队列实现进程间通信 系统开销比较大
进程的创建:
multiprocessing.Process(target=函数名,args=(参数))继承方式创建进程class 子类名(multiprocessing.Proces): def run(self): pass
进程间通信(传递数据 ):
q = multiprocessing.Queue(3) # 创建一个队列,可以指定可传递几个数据q.put () # 存 q.get() # 取 q.qsize() # 取消息数量 q.full() # 判断是否满了q.empty # 判断是否为空
进程池:
一个特殊的容器,里面创建了很多进程,重复利用进程作用:减少了创建,销毁进程的过程,提高了效率po = multiprocessing.Pool(3) # 定义一个进程池,最大进程数2po.apply_async(要调用的目标,(要传递的参数)) # async 异步po.close() # 关闭进程池po.join() # 等待所有的子进程执行完毕
今日内容
文件夹复制:
os.listdir() # 列出文件夹中所有的文件名os.path.getsize() # 获取文件的大小os.mkdir() # 新建文件夹Pool() # 创建进程池Manger().Queue() # 有进程池的时候,队列需要 Manger()中的Queue() with open("文件名", “rw”) as f: f.read() # 读 f.write() # 写
文件夹复制代码
import multiprocessing
import os, time
def save_folder(q, dw_folder_name, save_folder_name, file_name):
with open(dw_folder_name + "/" + file_name, "rb") as f:
content = f.read()
# 在新创建的文件中写入文件
with open(save_folder_name + "/" + file_name, "wb") as f2:
f2.write(content)
new_file_size = os.path.getsize(save_folder_name + "/" + file_name)
q.put(new_file_size)
def main():
# 提示用户输入文件夹名
dw_folder_name = input("请输入要下载的文件夹的名字:")
try:
# 创建一个新文件夹
save_folder_name = dw_folder_name + "[嘿嘿嘿]"
os.mkdir(save_folder_name)
except:
pass
# 获取目标文件夹中的所有的文件 os.listdir()
file_names = os.listdir(dw_folder_name)
# 添加进程池
po = multiprocessing.Pool(3)
# 创建队列
q = multiprocessing.Manager().Queue()
# 从目标文件夹中读取文件
for file_name in file_names:
po.apply_async(save_folder, (q, dw_folder_name, save_folder_name, file_name))
po.close()
# po.join()
# 获取文件夹的大小
folder_size = 0
for old_file in file_names:
old_file_s = os.path.getsize(dw_folder_name + "/" + old_file)
folder_size += old_file_s
print("文件夹总大小为: %d" % folder_size)
new_file_size = 0
# 显示进度
while True:
s = q.get()
new_file_size += s
time.sleep(0.1)
print("拷贝的进度为: %.2f %%" % (new_file_size / folder_size * 100), end="")
if new_file_size >= folder_size:
break
print()
if __name__ == "__main__":
main()
进程池中的进程出现异常不会显示