创建进程Process
multiprocessing模块就是跨平台版本的多进程模块,提供一个Process类来代表一个进程对象,这个对象可以理解为是一个独立的过程,可以执行另外的操作。
创建子进程时,只需要传入一个执行函数和函数的参数,创建一个Process实例,用start()方法启动。
import multiprocessing
import time
def test1():
while True:
print("---1----")
time.sleep(1)
def test2():
while True:
print("---2---")
time.sleep(1)
def main():
t1 = multiprocessing.Process(target=test1)
t2 = multiprocessing.Process(target=test2)
t1.start()
t2.start()
if __name__ == "__main__":
main()
主进程有什么子进程就有什么 代码+资源=进程
线程和进程都可以完成多任务,但进程耗费的资源比较大,一个操作系统上进程数越多,浪费的资源也越多,效率也越低。
进程:能够完成任务,如电脑上能够运行多个QQ
线程:也能够完成多任务,如一个QQ中有多个聊天窗口。
一个进程中至少有一个主线程。
进程是资源分配的单位,线程是操作系统调度的单位。
线程不能独立执行,必须存在内存中。
可将进程理解为一条流水线,而其中的线程就是这个流水线上的工人。
进程间的通信:(一种方式是socket),另一种是Queue 队列(先进先出)
import multiprocessing
def test1(q1):
#模拟从网上下载的数据
data = [11,22,33,44,55]
#向队列中写入数据
for temp in data:
q1.put(temp)
print("下载器已经下载完数据并存入队列中")
def test2(q1):
list_data = list()#创建列表可以直接写list 可读性强
#从队列中获取数据
while True:
datas = q1.get()
list_data.append(datas)
if q1.empty():#如果队列中的数据为空了 就返回
break
#模拟数据处理
print(list_data)
def main():
#创建一个队列
q1 = multiprocessing.Queue()
#创建多个进程 将队列的引用当做实参进行传递
p1 = multiprocessing.Process(target=test1,args=(q1,))
p2 = multiprocessing.Process(target=test2,args=(q1,))
#相当于两个进程 一个进程往里面写东西 一个进程读东西
p1.start()
p2.start()
if __name__ == "__main__":
main()
进程池
池就是缓存 缓冲。当需要创建的子进程数量不多时,可以直接利用multiprocessing中的Process动态生成多个进程,但如果上千个目标,手动的创建进程工作量太大,就可以利用multiprocessing模块的Pool方法。
初始化进程池时候 可以指定一个最大进程数,当有新的请求提交到Pool中时,如果池还没有满,就会创建一个新的进程来执行该请求,但如果池中进程数已经达到最大值,那么该请求就会等待,直到池中的进程结束,才会用之前的进程执行新的任务。
from multiprocessing import Pool
import time,os,random
def worker(mes):
t_start = time.time()
print('%s 开始执行 进程号为 %d' % (mes,os.getpid()))
#random.random()随机生成0-1之间的浮点数
time.sleep(random.random()*2)
t_stop = time.time()
print(mes,'执行完毕 耗时%0.2f' % (t_stop-t_start))
po = Pool(3)
for i in range(1,10):
#Pool().apply asyns(要调用的目标,(传递给目标的参数元祖,))
#每次循环将会用空闲下来的子进程去调用目标
po.apply_async(worker,(i,))
po.close()#关闭进程池 关闭后po不再接受新的请求
po.join()#等待po中所有进程执行完毕 必须放在close之后
多任务copy文件夹中的文件
import multiprocessing
import time
import os
def copy_file(name,old_folder_name,new_fplder_name):
#完成文件的复制
old_f = open(old_folder_name + '/'+name,'rb')
contend = old_f.read()
old_f.close()
new_f = open(new_fplder_name + '/' + name,'wb')
new_f.write(contend)
new_f.close()
def main():
#1 获取用户要copy的文件夹名字
old_folder_name = input('请输入要copy的文件夹:')
#2 创建一个新的文件夹
try:#保证文件夹存在 不存在创建 存在不创建
new_fplder_name = old_folder_name + '复件'
os.mkdir(new_fplder_name)
except:
pass
#3 获取文件夹中所有的文件名字
file_name = os.listdir(old_folder_name)
print(file_name)
#4 创建进程池
# 5 复制文件夹中的文件 到新文件夹
po = multiprocessing.Pool(5)
for name in file_name:
po.apply_async(copy_file,args=(name,old_folder_name,new_fplder_name))
po.close()
po.join()
if __name__ == "__main__":
main()