进程池
在使用Python进行系统管理时,特别是同时操作多个文件目录或者远程控制多台主机,并行操作可以节约大量的时间。如果操作的对象数目不大时,还可以直接使用Process类动态的生成多个进程,十几个还好,但是如果上百个甚至更多,那手动去限制进程数量就显得特别的繁琐,此时进程池就派上用场了。Pool类可以提供指定数量的进程供用户调用,当有新的请求提交到Pool中时,如果池还没有满,就会创建一个新的进程来执行请求。如果池满,请求就会告知先等待,直到池中有进程结束,才会创建新的进程来执行这些请求。
Pool类中方法
apply():
函数原型:apply(func[, args=()[, kwds={}]])
该函数用于传递不定参数,主进程会被阻塞直到函数执行结束(不建议使用,并且3.x以后不再使用)。
map()
函数原型:map(func, iterable[, chunksize=None])
Pool类中的map方法,与内置的map函数用法行为基本一致,它会使进程阻塞直到返回结果。
注意,虽然第二个参数是一个迭代器,但在实际使用中,必须在整个队列都就绪后,程序才会运行子进程。
返回结果为一个list,序列传入func后执行结果的list;
close()
关闭进程池(Pool),使其不再接受新的任务。
terminate()
立刻结束工作进程,不再处理未处理的任务。
join()
使主进程阻塞等待子进程的退出,join方法必须在close或terminate之后使用。
获取CPU的核数
multiprocessing.cpu_count() #获取cpu的核数
创建进程池
示例1:
#coding=utf-8
import multiprocessing
import os,time
import random
def m1(x):
time.sleep(random.random() * 4)
print("pid: ",os.getpid(), x*x)
return x*x
if __name__ == "__main__":
pool = multiprocessing.Pool(multiprocessing.cpu_count())
i_list = range(8)
res =pool.map(m1,i_list)#函数
print (type(res))
print(res)
示例2:
#coding=utf-8
import multiprocessing
import os,time
import random
def f(x):
return x * x
if __name__ == "__main__":
pool = multiprocessing.Pool(processes = 4)
#执行进程池中的一个子进程,执行结果存放在result中
result = pool.apply_async(f,[10])
print(result.get(timeout=1))#获取执行结果
#多进程执行进程池中的进程
print(pool.map(f,range(10)))
多进程与单进程执行时间比较
#coding=utf-8
import time
from multiprocessing import Pool
def run(fn):
time.sleep(1)
return fn*fn
if __name__ == "__main__":
testFL = [1,2,3,4,5,6]
print("单进程执行: ")
start = time.time()
for fn in testFL:
run(fn)
end = time.time()
print("顺序执行时间: ",end - start)
pool = Pool(5)#创建包含5个进程的进程池
t = time.time()
res = pool.map(run,testFL)
pool.close()#关闭进程池,不再接受新的任务
pool.join()#等待子进程执行结果退出
end = time.time()
print("进程池并行执行时间: ",end - t)
print(res)
Multiprocessing.Queue方法
>>> q = Queue()
>>> q.put(1)
>>> q.put(1)
>>> q.put(2)
>>> q.get()
1
>>> q.qsize()
2
>>> q.empty()
False
>>> q.full()
False
>>> q.get(timeout=1)
1
>>> q.get()
2
同步进程
使用Queue 同步进程间数据
示例1:
#coding=utf-8
from multiprocessing import Queue,Process
def func(queue):
queue.put("通过队列同步的消息!")
if __name__ == "__main__":
q = Queue()#此处队列q为主进程的
p = Process(target = func,args=(q,))
#主进程、子进程是两个独立的进程,数据不共享
#生成子进程,通过主进程定义的队列q同步主、子进程消息
p.start()
p.join()
print("主进程和子进程同步的队列消息:",q.get())#获取同步的队列数据
multiprocessing.Queue类似于queue.Queue,一般用来多个进程间交互信息。Queue是进程和线程安全的。它实现了queue.Queue的大部分方法,但task_done()和join()没有实现。multiprocessing.JoinableQueue是multiprocessing.Queue的子类,增加了task_done()方法和join()方法。task_done():用来告诉queue一个task完成。一般在调用get()时获得一个task,在task结束后调用task_done()来通知Queue当前task完成。join():阻塞直到queue中的所有的task都被处理(即task_done方法被调用)。
示例2:
#coding=utf-8
from multiprocessing import Process,Queue
import random,time
def write(q):
for value in ["A","B","C"]:
print("Put %s to queue." %value)
q.put(value)
time.sleep(random.random())
def read(q):
time.sleep(1)
while not q.empty():
print("Get %s from queue." %q.get(True))
if __name__ == "__main__":
q = Queue()#主进程定义的队列
p1 = Process(target=write,args=(q,))#两个子进程同步进程数据
p2 = Process(target=read,args=(q,))
p1.start()
p2.start()
p1.join()
p2.join()
print("Done!")
示例3:
进程池间同步数据需要使用Manager里面的Queue
#encoding=utf-8
from multiprocessing import Pool,Manager
def func(q):
print("*"*10)
q.put("12346")
if __name__ == "__main__":
manager = Manager()
q = manager.Queue()
pool = Pool(processes=4)
for i in range(5):
pool.apply_async(func,(q,))
pool.close()
pool.join()
print(q.qsize())
多进程(二)
原创
©著作权归作者所有:来自51CTO博客作者qq5a16e6241946e的原创作品,请联系作者获取转载授权,否则将追究法律责任

提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
java 多进程
一个项目分多进程目的是为了分解压力。
java 项目 -
多进程续集
守护进程,互斥锁,队列(Queue),生产者消费者模型
守护进程互斥锁队列生产者消费者模型