进程间通信
概念:
函数:
block = false 和timeout不能并行实行
block = false 一旦阻塞就报错
timeout 在超过设置时间后 再报错
简单代码演示:
"""
消息队列
"""
from multiprocessing import Process, Queue
from time import sleep
# 创建消息队列
q = Queue(3)
def bar():
for i in range(5):
sleep(2)
q.put(i)
def foo():
while True:
try:
print(q.get(timeout=3))
except:
return
p1 = Process(target = bar)
p2 = Process(target = foo)
p1.start()
p2.start()
p1.join()
p2.join()
运行结果:
0
1
2
3
4
Process finished with exit code 0
虽然消息队列设置的3个 但是:print(q.get(timeout=3)) 也同时在取 所以五个数都能取出
案例练习:拷贝目录
代码实现:
"""
使用进程池拷贝一个目录及目录中所有内容, 实时显示拷贝的百分比
× 目录中的内容均为普通文件
× 进程池中执行的每个进程事件拷贝一个文件
"""
from multiprocessing import Pool, Queue
import os
q = Queue() # 消息队列
# 复制文件
def copy_file(file, old_folder, new_folder):
fr = open(old_folder+'/'+file, 'rb')
fw = open(new_folder+'/'+file, 'wb')
# 开始拷贝
while True:
data = fr.read(1024*1024)
break
n = fw.write(data) # 返回写入多少字节
q.put(n) # 放入消息队列
fr.close()
fw.close()
def main():
base_path = "拷贝这个基准目录下的目录 eg:/home/tarena/"
dir = input("输入你要拷贝的目录:")
old_folder = base_path + dir # 待拷贝目录
# 目标位置
new_folder = old_folder+'备份'
os.mkdir(new_folder) # 创建目录
all_file = os.listdir(old_folder) # 获取文件列表
# 计算目录大小
totle_size = 0
for file in all_file:
totle_size += os.path.getsize(old_folder+'/'+file)
# 创建进程池
pool = Pool()
for file in all_file:
# 每个copy_file复制一个文件
pool.apply_async(copy_file, args=(file, old_folder, new_folder))
pool.close()
print("目录大小:%.2fM"%(totle_size/1024/1024))
copy_size = 0
while True:
copy_size += q.get()
print("拷贝了%.1f%%"%(copy_size/totle_size*100))
if copy_size >= totle_size:
break
pool.join()
main()