python真正实现多线程_python多线程实现
概念介紹
同步&異步
同步:所謂同步是一個服務(wù)的完成需要依賴其他服務(wù)時,只有等待被依賴的服務(wù)完成后,依賴的服務(wù)才能算完成,這是一種可靠的服務(wù)序列。要么成功都成功,失敗都失敗,服務(wù)的狀態(tài)可以保持一致。
異步:所謂異步是一個服務(wù)的完成需要依賴其他服務(wù)時,只通知其他依賴服務(wù)開始執(zhí)行,而不需要等待被依賴的服務(wù)完成,此時該服務(wù)就算完成了。至于被依賴的服務(wù)最終是否真正完成,無法確定,所以它是不可靠的服務(wù)序列。
阻塞&非阻塞
阻塞:阻塞調(diào)用是指調(diào)用結(jié)果返回之前,當(dāng)前線程會被掛起,一直處于等待消息通知,不能夠執(zhí)行其他業(yè)務(wù)。函數(shù)只有在得到結(jié)果之后才會返回。
非阻塞:非阻塞和阻塞的概念相對應(yīng),指在不能立刻得到結(jié)果之前,該函數(shù)不會阻塞當(dāng)前線程,而會立刻返回。
python的multiprocessing主要利用python的Multiprocessing庫中的Pool來實(shí)現(xiàn),它可以提供指定數(shù)量的進(jìn)程供用戶調(diào)用,當(dāng)有新的請求提交到pool中時,如果池還沒有滿,那么就會創(chuàng)建一個新的進(jìn)程用來執(zhí)行該請求;但如果池中的進(jìn)程數(shù)已經(jīng)達(dá)到規(guī)定最大值,那么該請求就會等待,直到池中有進(jìn)程結(jié)束,才會創(chuàng)建新的進(jìn)程來執(zhí)行它。
Pool介紹
Pool類用于需要執(zhí)行的目標(biāo)很多,而手動限制進(jìn)程數(shù)量又太繁瑣的情況。
構(gòu)造方法
Pool([processes[, initializer[, initargs[, maxtasksperchild[, context]]]]])
processes:使用的工作進(jìn)程的數(shù)量,如果processes是None那么使用 os.cpu_count()返回的數(shù)量。
initializer:如果initializer是None,那么每一個工作進(jìn)程在開始的時候會調(diào)用initializer(*initargs)。
maxtasksperchild:工作進(jìn)程退出之前可以完成的任務(wù)數(shù),完成后用一個新的工作進(jìn)程來替代原進(jìn)程,來讓閑置的資源被釋放。maxtasksperchild默認(rèn)是None,意味著只要Pool存在工作進(jìn)程就會一直存活。
context:用在制定工作進(jìn)程啟動時的上下文,一般使用 multiprocessing.Pool() 或者一個context對象的Pool()方法來創(chuàng)建一個池,兩種方法都適當(dāng)?shù)脑O(shè)置了context。者一個context對象的Pool()方法來創(chuàng)建一個池,兩種方法都適當(dāng)?shù)脑O(shè)置了context。
實(shí)例方法
apply_async(func[, args[, kwds[, callback]]]) 它是非阻塞。
apply(func[, args[, kwds]])是阻塞的。
close() 關(guān)閉pool,使其不在接受新的任務(wù)。
terminate() 關(guān)閉pool,結(jié)束工作進(jìn)程,不在處理未完成的任務(wù)。
join() 主進(jìn)程阻塞,等待子進(jìn)程的退出, join方法要在close或terminate之后使用。
異步進(jìn)程池
from multiprocessing import Pool
def test(i):
print i
if __name__=="__main__":
pool = Pool(processes=10)
for i in xrange(500):
'''
For循環(huán)中執(zhí)行步驟:
(1)循環(huán)遍歷,將500個子進(jìn)程添加到進(jìn)程池(相對父進(jìn)程會阻塞)
(2)每次執(zhí)行10個子進(jìn)程,等一個子進(jìn)程執(zhí)行完后,立馬啟動新的子進(jìn)程。(相對父進(jìn)程不阻塞)
apply_async為異步進(jìn)程池寫法。
異步指的是啟動子進(jìn)程的過程,與父進(jìn)程本身的執(zhí)行(print)是異步的,而For循環(huán)中往進(jìn)程池添加子進(jìn)程的過程,與父進(jìn)程本身的執(zhí)行卻是同步的。
'''
pool.apply_async(test, args=(i,)) #維持執(zhí)行的進(jìn)程總數(shù)為10,當(dāng)一個進(jìn)程執(zhí)行完后啟動一個新進(jìn)程.
print “test”
pool.close()
pool.join()
執(zhí)行順序:For循環(huán)內(nèi)執(zhí)行了2個步驟,第一步:將500個對象放入進(jìn)程池(阻塞)。第二步:同時執(zhí)行10個子進(jìn)程(非阻塞),有結(jié)束的就立即添加,維持10個子進(jìn)程運(yùn)行。(apply_async方法的會在執(zhí)行完for循環(huán)的添加步驟后,直接執(zhí)行后面的print語句,而apply方法會等所有進(jìn)程池中的子進(jìn)程運(yùn)行完以后再執(zhí)行后面的print語句)
注意:
調(diào)用join之前,先調(diào)用close或者terminate方法,否則會出錯。執(zhí)行完close后不會有新的進(jìn)程加入到pool,join函數(shù)等待所有子進(jìn)程結(jié)束。
同步進(jìn)程池(阻塞)
from multiprocessing import Pool
def test(p):
print p
time.sleep(3)
if __name__=="__main__":
pool = Pool(processes=10)
for i in xrange(500):
'''
實(shí)際測試發(fā)現(xiàn),for循環(huán)內(nèi)部執(zhí)行步驟:
(1)遍歷500個可迭代對象,往進(jìn)程池放一個子進(jìn)程
(2)執(zhí)行這個子進(jìn)程,等子進(jìn)程執(zhí)行完畢,再往進(jìn)程池放一個子進(jìn)程,再執(zhí)行。(同時只執(zhí)行一個子進(jìn)程)
for循環(huán)執(zhí)行完畢,再執(zhí)行print函數(shù)。
'''
pool.apply(test, args=(i,)) #維持執(zhí)行的進(jìn)程總數(shù)為10,當(dāng)一個進(jìn)程執(zhí)行完后啟動一個新進(jìn)程.
print “test”
pool.close()
pool.join()
說明:
for循環(huán)內(nèi)執(zhí)行的步驟順序,往進(jìn)程池中添加一個子進(jìn)程,執(zhí)行子進(jìn)程,等待執(zhí)行完畢再添加一個子進(jìn)程…..等500個子進(jìn)程都執(zhí)行完了,再執(zhí)行print “test”。(從結(jié)果來看,并沒有多進(jìn)程并發(fā))
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的python真正实现多线程_python多线程实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python界面开发pyqt_Pytho
- 下一篇: python绘制3d动态模型_怎么用py