您的位置:首页 > 编程语言 > Python开发

python:Process、join()、进程的创建Process子类、进程池Pool、将一个文件夹的内容copy到另一个文件夹

2017-07-18 10:19 811 查看
multiprocessing中的Process是一个类

from multiprocessing import Process
import os
#子进程要执行的代码
def run_proc(name):
print("子进程运行中,name=%s,pid=%d..."%(name,os.getpid()))

if __name__=='__main__':
print("父进程%d"%os.getpid())
p=Process(target=run_proc,args=('test',))#这里传过去的参数是元组,代表只有一个参数
print("子进程要执行")
p.start()
p.join()
print("子进程结束")
'''
父进程6652
子进程要执行
子进程运行中,name=test,pid=1524...
子进程结束
'''


p=Process(target)#这个是创建的p,可以当做一个进程,进程start后,执行的是Process中的target

在fork()中创建的子进程,父进程和子进程各自独立的进行,不会相互等待

但是在multiprocessing中,父进程会等到子进程运行完后才结束

p.join()等待进程结束

from multiprocessing import Process
import time
import random

def test():
for i in range(random.randint(1,5)):
print("----子进程中%d___"%i)
time.sleep(1)

if __name__=='__main__':
p=Process(target=test)
p.start()
p.join()#这句话保证子进程结束后再向下执行
#p.join(2)#等待2s
#p.terminate() #进行结束
print("----等待子进程结束后进行-----")

#整个子进程结束后主进程才结束,p.join保证p进程结束后,才继续向下执行
'''
----子进程中0___
----子进程中1___
----等待子进程结束后进行-----
'''


Demo:(创建子进程)

创建进程有两种方式:利用Process,另外继承Process类

p.start 一定会调用run方法执行

另外一种创建子进程的方式

#创建新的进程还能够使用类的方式,可以自定义一个类,继承Process类,每次
#实例化这个类的时候,就等同于实例化一个进程对象
from multiprocessing import Process
import time
import os

startTime=time.time()
time.ctime()#Tue Jul 18 10:49:52 2017

#创建进程有两种方式:利用Process,另外继承Process类
#p.start 一定会调用run方法执行
#另外一种创建子进程的方式

#继承Process类
class MyNewProcess(Process):
#因为Process类本身也有__init__方法,这个子类相当于重写了这个方法
#我们并没有完全初始化一个Process类,最好的方法就是讲继承类本身传递给
#Process.__init__方法,完成这些初始化操作
def __init__(self):
Process.__init__(self)
def run(self):
for i in range(5):
print("-运行run方法,id is %d---"%os.getpid())
time.sleep(1)

if __name__=='__main__':
p=MyNewProcess()
p.start()

endTime=time.time()#1500346213.4717257
timeN=endTime-startTime
print("这是一种计算程序运行的时间t=%0.5f,id is %d"%(timeN,os.getpid()))
'''
这是一种计算程序运行的时间t=0.17700,id is 9992
这是一种计算程序运行的时间t=0.00000,id is 9224
-运行run方法,id is 9224---
-运行run方法,id is 9224---
-运行run方法,id is 9224---
-运行run方法,id is 9224---
-运行run方法,id is 9224---
'''

class MyProcess(Process):
def __init__(self):
Process.__init__(self)

def run(self):
"""要执行的任务代码写在run方法中"""
for i in range(5):
print("子进程:%d,正在运行。。。%d" % (os.getpid(), i))
time.sleep(1)

def main():
print("父进程:%d,正在运行。。。" % os.getpid())
p = MyProcess()
p.start()
p.join()

if __name__ == '__main__':
# main()
p1 = MyProcess()
p1.start()

'''
子进程:9804,正在运行。。。0
子进程:9804,正在运行。。。1
子进程:9804,正在运行。。。2
子进程:9804,正在运行。。。3
子进程:9804,正在运行。。。4
'''


进程池

pool 

pool=Pool(3)#表示进程池最多有3个进程一起执行

pool.apply_async(workr,(i,))#向进程池中添加任务

如果添加的任务数量超过了进程池中进程的个数的话,也不会导致添加不进去

添加到进程中的任务,如果还没有被执行的话,那么此时他们会等待进程池中的

经常完成一个任务后,会自动的去用刚刚的那个进程,完成当前的新任务

pool.close()关闭进程池,相当于不能够再次添加新任务了

pool.join()主进程 创建/添加 任务后,默认不会等待进程池中的任务执行完后才结束,

而是主进程的任务结束后,立马结束,如果没有join(),会导致进程池的任务不会执行

等待pool中所有的子进程执行完毕

这种方式下:一般主进程用来等待,真正的任务都是在子进程中完成

非堵塞式添加进程到进程池:

from multiprocessing import Pool
import os
import time
import random

def worker(msg):
t_start=time.time() #记录从1970.0.0到现在的秒数
print("%s 开始执行,进程号为%d"%(msg,os.getpid()))
#random.random()随机生成0~1之间的浮点数
time.sleep(random.random()*2)
t_stop=time.time()
print(msg,"执行完毕,耗时%0.2f"%(t_stop-t_start))

if __name__=="__main__":
po=Pool(3) #定义一个进程池,最大进程数3
for i in range(0,10):
po.apply_async(worker,(i,))
print("---start---")
po.close()#关闭进程池,关闭后po不再接受新的请求
po.join()#等待po中所有子进程执行完成,必须放在close后
print("-----------end----------")
'''
---start---
0 开始执行,进程号为11856
0 执行完毕,耗时1.19
4 开始执行,进程号为11856
4 执行完毕,耗时1.97
2 开始执行,进程号为12104
2 执行完毕,耗时0.73
3 开始执行,进程号为12104
3 执行完毕,耗时0.63
6 开始执行,进程号为12104
6 执行完毕,耗时1.86
1 开始执行,进程号为10656
1 执行完毕,耗时1.38
5 开始执行,进程号为10656
5 执行完毕,耗时0.36
7 开始执行,进程号为10656
7 执行完毕,耗时0.76
8 开始执行,进程号为10656
8 执行完毕,耗时0.15
9 开始执行,进程号为10656
9 执行完毕,耗时1.98
-----------end----------
'''


堵塞式添加进程到进程池,正常情况是一次放到进程池中,当执行完一个进程后,再次添加新的任务

from multiprocessing import Pool
import os
import time
import random

def worker(msg):
t_start=time.time() #记录从1970.0.0到现在的秒数
print("%s 开始执行,进程号为%d"%(msg,os.getpid()))
#random.random()随机生成0~1之间的浮点数
time.sleep(random.random()*2)
t_stop=time.time()
print(msg,"执行完毕,耗时%0.2f"%(t_stop-t_start))

if __name__=="__main__":
po=Pool(3) #定义一个进程池,最大进程数3
for i in range(0,10):
po.apply(worker,(i,))#等待上一次任务完成之后再次添加新的任务,堵塞式添加

print("---start---")
po.close()#关闭进程池,关闭后po不再接受新的请求
po.join()#等待po中所有子进程执行完成,必须放在close后
print("-----------end----------")
'''
---start---
1 开始执行,进程号为11924
1 执行完毕,耗时0.97
4 开始执行,进程号为11924
4 执行完毕,耗时0.33
7 开始执行,进程号为11924
7 执行完毕,耗时1.56
2 开始执行,进程号为12056
2 执行完毕,耗时0.95
5 开始执行,进程号为12056
5 执行完毕,耗时1.62
8 开始执行,进程号为12056
8 执行完毕,耗时0.60
0 开始执行,进程号为1736
0 执行完毕,耗时1.14
3 开始执行,进程号为1736
3 执行完毕,耗时0.40
6 开始执行,进程号为1736
6 执行完毕,耗时0.94
9 开始执行,进程号为1736
9 执行完毕,耗时0.20
-----------end----------
'''

copy文件夹

import os
#创建文件夹 os.mkdir("new")
#os.listdir("文件夹名")#显示文件夹下所有的文件

#copy一个文件夹

def copyFileTask(name,oldFolderName,newFolderName):
fr=open(oldFolderName+"/"+name)
fw=open(newFolderName+"/"+name)

content=fr.read()
fw.write(content)

fr.close()
fw.close()

def main():
#获取永远要copy的文件夹的名字
oldFolderName=input("请输入文件夹的名字")
newFolderName=oldFolderName+"复件"
#创建一个文件夹
os.mkdir(newFolderName)

#获取old文件夹中所有的文件名字
fileNames=os.listdir(oldFolderName)

pool=Pool(5)#使用多进程的方式copy原文件夹中的所有文件到新的文件夹中
queue=Manager().Queue()

for name in fileNames:
pool.apply_async(copyFileTask,args=(name,oldFolderName,newFolderName,queue))

num=0
allNum=len(fileNames)
while True:
queue.get()
num+=1
copyRate=num/allNum
print("\r copy 的进度为:%.2f%%"%(copyRate*100),end="")
if num==allNum:
break

pool.close()
pool.join()

if __name__="__main__":
main()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐