什么是进程?
-
程序:一个未运行的二进制文件,叫做程序。如Windows下的PE文件
-
进程:二进制文件运行后,文件本身以及用到的资源称为进程,他是操作系统分配资源的基本单元。
-
多任务:不止可以通过线程完成多任务,还可以通过进程完成多任务。
使用Process实现多进程
from multiprocessing import Process
import time
def test(test):
time.sleep(5)
print("这是{}".format(test))
def main():
p1 = Process(target=test,kwargs={"test":"t1"})
p2 = Process(target=test,kwargs={"test":"t2"})
p1.start()
p2.start()
if __name__ == "__main__":
main()
通过队列完成进程间通信
from multiprocessing import Queue,Process
import time
import os
def queue_put(q):
for i in range(10):
q.put(i)
print("PID:{} ,{} 已存入队列,当前队列共{}个元素".format(os.getpid(),i,q.qsize()))
time.sleep(5)
def queue_get(q):
for i in range(10):
print("PID:{} ,{} 已取出队列,当前队列共{}个元素".format(os.getpid(),q.get(),q.qsize()))
time.sleep(5)
def main():
q = Queue(5)#创建一个队列,队列可以存储5个数据
# q.put("a")#向队列中添加数据,如果队列存满,程序会阻塞等待
# q.get()#从队列中获取数据,如果队列为空,程序会阻塞等待
# #q.put_nowait()如果队列存满,程序会报异常
# #q.get_nowait()如果队列为空,程序会报异常
# q.qsize()#取出队列中数据个数
# q.empty()#判断队列是否为空
# q.full()#判断队列是否存满
p1 = Process(target=queue_put,args=(q,))
p2 = Process(target=queue_get,args=(q,))
p1.start()
p2.start()
if __name__ == "__main__":
main()
进程池
import hashlib
from multiprocessing import Pool
def js_hash(s):
md5 = hashlib.md5()
md5.update(s.encode('utf-8'))
md5 = md5.hexdigest()
if '0e' == md5[0:2] and md5[2:].isdecimal():
print(s,md5)
if __name__ == '__main__':
p = Pool(5)#创建一个进程池,最大进程数5
for i in range(0,99999999999999):
s = '0e' + str(i)
p.apply_async(js_hash, args=(s,))#apply_async(要调用的目标,args=(传递的参数,))
p.close()#关闭进程池,关闭后进程池不再接受新的请求
p.join()#等待所有子进程执行完毕,必须放在close语句后
案例:多任务文件copy
import os,sys
from multiprocessing import Pool,Manager
def copy_file(q,file_name,old_dir,new_dir):
#print("将 {} 文件复制到 {} 目录下".format(file_name,new_dir))
if os.path.isdir(old_dir + "\\" + file_name):
# print(file_name,"是个目录")
q.put(file_name)
else:
#print(file_name,"是个文件")
with open(old_dir + "\\" + file_name,'rb') as file:
with open(new_dir + "\\" + file_name,"wb") as file_new:
file_new.write(file.read())
def main():
# 1、获取要拷贝的文件名
print("注意!此程序不完善,尚不能copy文件夹中文件夹的文件")
old_dir = input(r"输入需要copy的源文件夹路径,如(C:\null):")
# 2、创建新文件夹
new_dir = input(r"输入需要copy的目标文件夹路径,如(C:\null_副件):")
try:
os.mkdir(new_dir)
except:
pass
# 3、获取所有需要copy文件名
files_name = os.listdir(old_dir)
# 4、创建进程池
po = Pool(5)
# 进程池使用队列需要使用Manager类下的Queue
q = Manager().Queue()
# 5、向进程池添加复制文件的任务
for file_name in files_name:
po.apply_async(copy_file,args=(q,file_name,old_dir,new_dir))
po.close()
#po.join()
copy_ok = 0
copy_num = len(files_name)
folders = []
while True:
copy_ok += 1
sys.stdout.write("\r拷贝进度:{:.2f}%".format(copy_ok*100/copy_num))
try:
folders.append(q.get_nowait())
except:
pass
#将未拷贝的文件夹存入列表
if copy_ok >= copy_num:
break
print("\n以下文件夹未复制:",",".join(folders))
if __name__ == "__main__":
main()