线程VS进程
创建
1,进程包:Process
frommultiprocessing import Process
p=Process(targer=,args=)
p.start()
p.join
注意:Process包没有close()方法
例如:
from multiprocessing import Process import multiprocessing import time def do(n): time.sleep(0.01) print '%s:start;value is:%d' %(multiprocessing.current_process().name,n) if __name__=='__main__': p1=Process(target=do,args=(1,)) p2=Process(target=do,args=(2,)) p3=Process(target=do,args=(3,)) for i in range(1,4): eval('p%d.start()'%i) for i in range(1,4): eval('p%d.join()'%i) print 'end'
2,线程包:Thread
fromthreading import Thread
p=Thread(targer=,arg=)
p.start()
p.join()
注:Thread包没有close()方法
import threading
import time
def do(n):
time.sleep(0.01)
print '%s:start;value is:%d' %(threading.currentThread().name,n)
t1=threading.Thread(target=do,args=(1,))
t2=threading.Thread(target=do,args=(2,))
t3=threading.Thread(target=do,args=(3,))
for i in range(1,4):
eval('t%d.start()'%i)
for i in range(1,4):
eval('t%d.join()'%i)
print 'end'
3,进程池
from multiprocessing import Pool
p=Pool([n])
p.map(func,seq)
p.close()
p.join()
或者是:
result=p.apply_async(func,args=)
result.get
p.close()
p.join()#是主进程阻塞到子进程退出
注意:进程池没有start方法,有close()和join()方法;join()方法在close()方法之后执行,如果进程池的方法为map和apply_async就没必要使用join方法,因为以上两个方法都是执行完毕子进程并返回结果后才会继续往下执行主进程,所以无需使用join方法
map方法
from multiprocessing import Pool import multiprocessing import time def do(n): time.sleep(0.1) print "%s:start;value is:%d" %(multiprocessing.current_process().name,n) if __name__=='__main__': p=Pool() p.map(do,range(5)) p.close() # p.join() print 'end'
结果:
PoolWorker-1:start;value is:0
PoolWorker-2:start;value is:1
PoolWorker-3:start;value is:2
PoolWorker-4:start;value is:3
PoolWorker-1:start;value is:4
end
注意点:
1,p.map(do,range(5))方法是异步阻塞:见下图,及时没有p.join()方法,主进程也会在最后执行
2,如果p=Pool()中没有定义进程个数,则会根据p.map(do,range(5))方法中需要多少进程来创建进程,比如下图例子创建了5个进程;如果p=Pool(3)中定义了进程个数,则只会创建指定的进程个数
如果将p=Pool()改为p=Pool(3)结果: PoolWorker-1:start;value is:0
PoolWorker-2:start;value is:1
PoolWorker-3:start;value is:2
PoolWorker-2:start;value is:4PoolWorker-1:start;value is:3
end
apply_aysnc方法
from multiprocessing import Pool import multiprocessing import time def do(n): time.sleep(1) print "%s:start;value is:%d" %(multiprocessing.current_process().name,n) if __name__=='__main__': p=Pool() for i in range(5): result=p.apply_async(do,args=(1,)) result.get() p.close() print 'main-end'
结果: PoolWorker-2:start;value is:1
PoolWorker-1:start;value is:2
PoolWorker-3:start;value is:3
PoolWorker-4:start;value is:4
main-end
注意:appy_async方法是异步非阻塞,上面例子中进程池中的进程异步执行,并返回结果,可以看到进程的返回结果不是顺序的,由此得出执行顺序为异步不阻塞。
但是无论进程中的时间等待设定为多少秒,都是执行完子进程的任务才会打印主进程的‘main-end’
4,线程池
线城池方法同进程池方法基本一致
from multiprocessing.dummy import Pool
map方法
from multiprocessing.dummy import Pool import threading import time def do(n): time.sleep(0.5) print '%s begin' %threading.currentThread().name return n*n if __name__=='__main__': p=Pool() r=p.map(do,range(5)) p.close() p.join() print r
结果:
Thread-3 beginThread-4 beginThread-1 beginThread-2 begin
Thread-3 begin
[0, 1, 4, 9, 16]
apply_async方法
from multiprocessing.dummy import Pool import threading import time def do(n): time.sleep(0.5) print '%s begin' %threading.currentThread().name return n*n if __name__=='__main__': p=Pool() for i in range(4): result=p.apply_async(do,args=(i,)) result.get() p.close()
总结
1, 多进程的代码必须在if__name__==’__main__’:里面;多线程则不需要
2, Process、Thread包方法:start(),join(),Process(target=,args=),Thread(target=,args=)
3, 进程线程池方法:p=Pool([n]),p.map(func,seq),r=p.apply_async(func,(I,))r.get(),p.close(),p.join();join方法必须在close方法之后