日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

Python有了concurrent的话mutiprocessing和threading还有存在的意义吗?

發(fā)布時間:2024/10/12 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python有了concurrent的话mutiprocessing和threading还有存在的意义吗? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Python3.2中引入的concurrent非常的好用,只用幾行代碼就可以編寫出線程池/進(jìn)程池,并且計算型任務(wù)效率和mutiprocessing.pool提供的poll和ThreadPoll相比不分伯仲,而且在IO型任務(wù)由于引入了Future的概念效率要高數(shù)倍。

而threading的話還要自己維護(hù)相關(guān)的隊列防止死鎖,代碼的可讀性也會下降,相反concurrent提供的線程池卻非常的便捷,不用自己操心死鎖以及編寫線程池代碼,由于異步的概念I(lǐng)O型任務(wù)也更有優(yōu)勢。

既然如此,如果不是為了向下兼容2.x,是不是可以完全沒有必要繼續(xù)使用mutiprocessing和threading了?concurrent如此的優(yōu)秀。

?

concurrent的確很好用,主要提供了ThreadPoolExecutor和ProcessPoolExecutor。一個多線程,一個多進(jìn)程。但concurrent本質(zhì)上都是對threading和mutiprocessing的封裝。看它的源碼可以知道。
ThreadPoolExecutor自己提供了任務(wù)隊列,不需要自己寫了。而所謂的線程池,它只是簡單的比較當(dāng)前的threads數(shù)量和定義的max_workers的大小,小于max_workers就允許任務(wù)創(chuàng)建線程執(zhí)行任務(wù)。可以看源碼

def _adjust_thread_count(self):# When the executor gets lost, the weakref callback will wake up# the worker threads.def weakref_cb(_, q=self._work_queue):q.put(None)# TODO(bquinlan): Should avoid creating new threads if there are more# idle threads than items in the work queue.if len(self._threads) < self._max_workers:t = threading.Thread(target=_worker,args=(weakref.ref(self, weakref_cb),self._work_queue))t.daemon = Truet.start()self._threads.add(t)_threads_queues[t] = self._work_queue

所以如果你自己維護(hù)隊列的話也沒問題,cocurrent內(nèi)部也是自己維護(hù)了一個隊列,它給你寫好了而已。
至于死鎖問題concurrent也會引起死鎖的問題。給你一個例子,運行看看

import time from concurrent.futures import ThreadPoolExecutordef wait_on_b():time.sleep(5)print(b.result()) # b will never complete because it is waiting on a.return 5def wait_on_a():time.sleep(5)print(a.result()) # a will never complete because it is waiting on b.return 6executor = ThreadPoolExecutor(max_workers=2) a = executor.submit(wait_on_b) b = executor.submit(wait_on_a)

ProcessPoolExecutor 內(nèi)部也是使用的mutiprocessing。能夠從充分利用多核的特性,擺脫GIL的限制。注意定義ProcessPoolExecutor(max_workers=2)的時候max_workers稍大于CPU的核數(shù),不能太大。ProcessPoolExecutor內(nèi)部維持了一個call_queue用于保持任務(wù)隊列,其類型是multiprocessing.Queue。還有一個管理隊列的線程。這可以說是cocurrent的一個優(yōu)化。
具體可以看源碼,self._adjust_process_count()其實就是開啟進(jìn)程執(zhí)行任務(wù),點進(jìn)去_adjust_process_count一看就知道。self._queue_management_thread是管理隊列的線程

if self._queue_management_thread is None:# Start the processes so that their sentinels are known. self._adjust_process_count()self._queue_management_thread = threading.Thread(target=_queue_management_worker,args=(weakref.ref(self, weakref_cb),self._processes,self._pending_work_items,self._work_ids,self._call_queue,self._result_queue))self._queue_management_thread.daemon = Trueself._queue_management_thread.start()_threads_queues[self._queue_management_thread] = self._result_queue

所以說cocurrent好用,就是它自己做了一些更好的處理,譬如維持隊列,管理隊列線程,不需要你再操心。當(dāng)然你也可以自己實現(xiàn)。你能用cocurrent實現(xiàn)的。用threading和mutiprocessing都能實現(xiàn),大不了自己再做些額外的工作。因為cocurrent本質(zhì)上核心也是用的這2個。當(dāng)然有了現(xiàn)成的更好的cocurrent最好了,直接拿來使用,省的自己再造輪子。所以說用哪個看個人熟悉程度,譬如我用的python2,就用不了cocurrent。只好用threading。

轉(zhuǎn)載于:https://www.cnblogs.com/tcppdu/p/10546939.html

總結(jié)

以上是生活随笔為你收集整理的Python有了concurrent的话mutiprocessing和threading还有存在的意义吗?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。