python多进程queue通信
两个进程并行执行,一个进程负责搜索exe文件,另一个进程负责把大于40M的exe搬运到一个目标目录(多进程和队列应用)
队列通信:在队列q末尾添加了一个结束标志,在‘移动进程’中以收到该标志作为判断进程是否结束的依据。
以下是我对于多线程和多进程的理解:
多个进程并行执行,进程之间独立执行,数据不共享,若要共享数据需要队列通信等方式;
多个线程并发执行,每个线程都是交替执行的,但是,由于cpu的执行速度实在是太快了,我们感觉就像所有线程都在同时执行一样,同一进程的线程之间的数据是共享的。
计算密集型任务的特点是要进行大量的计算,消耗cpu资源,全靠cpu的运算能力。所以要将cpu的执行速度用在计算上,而不是用在交替执行线程上,所以用多进程。
IO密集型任务的特点是cpu消耗很少,任务的大部分时间都是cpu在等IO (硬盘/内存) 的读写操作。涉及到网络、磁盘IO的任务都是IO密集型任务,对于IO密集型任务,IO速度远低于cpu计算速度,cpu有余力可以交替执行线程,线程越多,时间就应用得越充分,cpu效率越高,所以用多线程。 (这段为我自己的理解,若有不对,欢迎指正)
以下为查找进程的函数
'''
函数作用:(查找进程)寻找exe文件,并传到队列q中
参数说明:
path为传入的目录,在此目录下寻找exe
q:用于存放exe文件的队列
无返回值
'''
def look_exe(path, q,):
print('查找开始', format_timestamp(NowTime()))
for root, dirs, files in os.walk(path):
for file in files:
if file.split('.')[-1] == 'exe':
# 判断是否为exe文件
fullpath = os.path.join(root, file) # 获得exe文件的全路径
q.put(fullpath) # 放入队列
print('查找进程',file)
q.put('结束') # 将所有的exe装进队列后,在最后加上一个结束标志
print('查找结束', format_timestamp(NowTime()))
以下为移动进程的函数
'''
函数作用:(移动进程)从q中取出消息(exe文件的绝对路径),判断出大于40M时,将其移动到新的路径里
参数说明:
path为传入的目录,大于40M的exe文件将被移到此路径下
q:两个进程间数据的队列,里面存放exe文件的绝对路径
无返回值
'''
def exe_move(q, path,):
global normal_value
normal_value=40
print('移动开始', format_timestamp(NowTime()))
while True:
if not q.empty():
# 首先判断队列不为空,再取消息
exe_path = q.get(True) # 从队列中拿出来
if exe_path == '结束':
# 收到结束标志时,代表共享的数据已全部取出,移动进程可以结束
print('移动结束', format_timestamp(NowTime()))
break
if getDocSize(exe_path)>normal_value:
basename=os.path.basename(exe_path)
newpath=os.path.join(path,basename) # 合成新路径,用于存放大于40M的exe文件
shutil.copy(exe_path,newpath) #移动
print('移动',basename)
目录越大,越能体现多进程的优势。下面两张图为部分打印结果展示,根据’‘查找进程‘’和‘’移动‘’穿插据、两个进程的开始和结束时间可看出两个进程是同时进行的。
总体代码如下:
import os
import shutil
from multiprocessing import Process, Queue
from datetime import datetime
'''
函数作用:获取当前时间
返回值:当前时间
'''
def NowTime():
return datetime.Now() #获取当前时间
"""
函数作用:格式化日期时间
参数说明:
timestamp:时间(时间字符串)
返回值:格式化后的日期时间
"""
def format_timestamp(timestamp):
return timestamp.strftime('%Y-%m-%d %H:%M:%s.%f')[:-3] #格式化输出时间
'''
函数作用:防止上一次代码的运行结果影响这一次,将文件夹删除再新建,相当于清空文件夹中的内容
参数说明:path:新的文件夹路径
无返回值
'''
def docu(path):
if os.path.exists(path):
shutil.rmtree(path, ignore_errors=True)
os.makedirs(path)
else:
os.makedirs(path)
'''
函数作用:获取文件大小,并化为mb
参数说明:path为文件的绝对路径
返回值:单位为mb的文件大小值
'''
def getDocSize(path):
size = os.path.getsize(path)
size = float(size)
return size/(1024*1024) # 化为MB单位
'''
函数作用:(查找进程)寻找exe文件,并传到队列q中
参数说明:
path为传入的目录,在此目录下寻找exe
q:用于存放exe文件的队列
无返回值
'''
def look_exe(path, q,):
print('查找开始', format_timestamp(NowTime()))
for root, dirs, files in os.walk(path):
for file in files:
if file.split('.')[-1] == 'exe':
# 判断是否为exe文件
fullpath = os.path.join(root, file) # 获得exe文件的全路径
q.put(fullpath) # 放入队列
print('查找进程',file)
q.put('结束') # 将所有的exe装进队列后,在最后加上一个结束标志
print('查找结束', format_timestamp(NowTime()))
'''
函数作用:(移动进程)从q中取出消息(exe文件的绝对路径),判断出大于40M时,将其移动到新的路径里
参数说明:
path为传入的目录,大于40M的exe文件将被移到此路径下
q:两个进程间数据的队列,里面存放exe文件的绝对路径
无返回值
'''
def exe_move(q, path,):
global normal_value
normal_value=40
print('移动开始', format_timestamp(NowTime()))
while True:
if not q.empty():
# 首先判断队列不为空,再取消息
exe_path = q.get(True) # 从队列中拿出来
if exe_path == '结束':
# 收到结束标志时,代表共享的数据已全部取出,移动进程可以结束
print('移动结束', format_timestamp(NowTime()))
break
if getDocSize(exe_path)>normal_value:
basename=os.path.basename(exe_path)
newpath=os.path.join(path,basename) # 合成新路径,用于存放大于40M的exe文件
shutil.copy(exe_path,newpath) #移动
print('移动',basename)
if __name__ == "__main__" :
print('主进程开始', format_timestamp(NowTime()))
path=r'C:\using\大于40M的exe文件存放处'
docu(path) # 对文件夹的创建与移除
file_path = r'C:\正点原子'
q=Queue() # 创建队列
# 创建两个进程
p_look=Process(target=look_exe, args=(file_path,q,))
p_move=Process(target=exe_move,args=(q,path,))
# 开始进程
p_move.start()
p_look.start()
# 进程结束后进入主进程
p_look.join()
p_move.join()
print('end')
print('主进程结束',format_timestamp(NowTime()))
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。