标签:两种 proc 图片 The rabl col 猴子补丁 tip too
一 Process类
multiprocessing模块下的一个类
创建子进程。
有两种方法
方法一
from multiprocessing import Process
import os
def foo():
print(‘%s from foo‘%os.getpid())
def bar():
print(‘%s from bar‘ % os.getpid())
if __name__ == ‘__main__‘:
p1=Process(target=foo)
p2=Process(target=bar)
p1.start()
p2.start()
p1.join()
p2.join()
print(‘%s over‘%os.getpid())
输出:
13524 from foo 12848 from bar 12696 over
方法二
from multiprocessing import Process
import os
class Myprocess(Process):
def __init__(self,name):
super().__init__()
self.name=name
def run(self):
print(‘%s from %s‘ % (os.getpid(),self.name))
if __name__ == ‘__main__‘:
p1=Myprocess(‘foo‘)
p2=Myprocess(‘bar‘)
p1.start()
p2.start()
p1.join()
p2.join()
print(‘%s over‘ % os.getpid())
输出:
15260 from foo 5980 from bar 8844 over
二 Thread类
threading模块下的类
创建线程
有两种方法
与Process类一样。
三 Pool类
Pool类的方法:
p=Pool()
p.apply_async(),异步提交任务,生成ApplyResult对象
p.close()
p.join()
ApplyResult.get(),从ApplyResult对象中获取返回值。
from multiprocessing import Pool
import os,time
def foo():
time.sleep(1)
print(‘%s from foo‘%os.getpid())
return ‘foo‘
def bar():
time.sleep(2)
print(‘%s from bar‘ % os.getpid())
return ‘bar‘
if __name__ == ‘__main__‘:
p=Pool()
t1=time.time()
res1=p.apply_async(foo)
res2=p.apply_async(bar)
p.close()
p.join()
print(res1)
print(time.time()-t1) ##多出来的0.15秒是开启进程所花费的时间
t2=time.clock()
print(res1.get())
print(res2.get())
print(time.clock()-t2)
输出:
12468 from foo 8832 from bar <multiprocessing.pool.ApplyResult object at 0x00000126511CEE48> 2.1609864234924316 foo bar 2.1880321932470032e-05
map()方,比较常用。
官方介绍:
Apply `func` to each element in `iterable`, collecting the results
in a list that is returned.
废话少说,上代码
import time
from multiprocessing import Pool
def foo(x):
time.sleep(1)
return x*x
if __name__ == ‘__main__‘:
l = [1,2,3,4,5,6,7,8,9,10]
t1 = time.time()
p = Pool()
print(time.time()-t1)
res = p.map(foo,l) # 这行代码表示所有的进行都已经执行完了,并且每个进程的结果都拿到,放在了res中
print(time.time()-t1)
print(res,type(res))
p.close()
p.join()
print(time.time()-t1)
输出:
0.14187192916870117 2.2597498893737793 [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] <class ‘list‘> 2.401075601577759
四 gevent
gevent是一个基于协程的Python网络库。
单线程实现并发,协程。
需要用到猴子补丁。
方法:
g1=gevent.spawn(func):提交任务,生成Greenlet对象--g1。
g1.join(),阻塞,直到g1任务完成。
g1.value。从Greenlet对象g1中获取返回值。
import gevent
from gevent import monkey;monkey.patch_all()
import os,time
from threading import current_thread
def foo():
time.sleep(1)
print(‘%s %s from foo‘%(os.getpid(),current_thread().getName()))
def bar():
time.sleep(2)
print(‘%s %s from bar‘ % (os.getpid(),current_thread().getName()))
t1=time.time()
g1=gevent.spawn(foo)
g2=gevent.spawn(bar)
print(g1,g2)
g1.join()
g2.join()
print(time.time()-t1)
输出:
<Greenlet at 0x1e3fc1396d0: foo> <Greenlet at 0x1e3fc139800: bar> 7536 DummyThread-1 from foo 7536 DummyThread-2 from bar 2.0017032623291016 #可以看到协程开启进程花销非常小。
五 ProcessPoolExecutor
创建多进程
concurrent.futures库内的ProcessPoolExecutor类
executor=ProcessPoolExecutor():生成一个ProcessPoolExecutor对象;
future=executor.submit():提交任务,返回一个Future对象。
executor.shutdown()。相当于Pool类中的close()和join()
future.result():从Future对象中获取其返回值。
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
import os,time
from threading import current_thread
def foo():
time.sleep(1)
print(‘%s %s from foo‘%(os.getpid(),current_thread().getName()))
return ‘foo‘
def bar():
time.sleep(2)
print(‘%s %s from bar‘ % (os.getpid(),current_thread().getName()))
return ‘bar‘
if __name__ == ‘__main__‘:
t1=time.time()
executor=ProcessPoolExecutor()
print(‘executor‘,executor)
future1=executor.submit(foo)
future2=executor.submit(bar)
print(future1,future2)
executor.shutdown()
print(future1.result())
print(future2.result())
print(time.time()-t1)
输出:
6480 MainThread from foo 6756 MainThread from bar foo bar 2.7526917457580566 #可以看到创建进程还是比较花费时间的
六 ThreadPoolExecutor()
创建多线程
concurrent.futures库内的ProcessPoolExecutor类
executor=ThreadPoolExecutor():生成一个ThreadPoolExecutor对象;
future=executor.submit():提交任务,返回一个Future对象。
executor.shutdown()。相当于Pool类中的close()和join()。
future.result():从Future对象中获取其返回值。
from concurrent.futures import ThreadPoolExecutor
import os,time
from threading import current_thread
def foo():
time.sleep(1)
print(‘%s %s from foo‘%(os.getpid(),current_thread().getName()))
return ‘foo‘
def bar():
time.sleep(2)
print(‘%s %s from bar‘ % (os.getpid(),current_thread().getName()))
return ‘bar‘
if __name__ == ‘__main__‘:
t1=time.time()
executor=ThreadPoolExecutor()
print(‘executor‘,executor)
future1=executor.submit(foo)
future2=executor.submit(bar)
print(future1,future2)
executor.shutdown()
print(future1.result())
print(future2.result())
print(time.time()-t1)
输出:
executor <concurrent.futures.thread.ThreadPoolExecutor object at 0x0000020073EAAAC8> <Future at 0x20073eb4198 state=running> <Future at 0x20074176940 state=running> 4380 <concurrent.futures.thread.ThreadPoolExecutor object at 0x0000020073EAAAC8>_0 from foo #可以看到进程号是一样的 4380 <concurrent.futures.thread.ThreadPoolExecutor object at 0x0000020073EAAAC8>_1 from bar foo bar 2.001234531402588 #相比较开启进程,线程开启的时间非常快,花销非常小
Process类,Thread类,Pool类,gevent类,ProcessPoolExecutor,ThreadPoolExecutor的用法比较
标签:两种 proc 图片 The rabl col 猴子补丁 tip too
原文地址:https://www.cnblogs.com/ExMan/p/10138866.html