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