<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Python多線程編程技術(shù)總結(jié)

          共 4251字,需瀏覽 9分鐘

           ·

          2021-01-28 21:04

          學(xué)習(xí)并發(fā)編程

          • 加速程序的運(yùn)行
          • 高薪程序員必備能力

          程序運(yùn)行的5種并發(fā)粒度

          • 單線程
          • 單線程多協(xié)程
          • 多線程
          • 多進(jìn)程
          • 多機(jī)器

          怎樣選擇并發(fā)技術(shù)

          • 如果單機(jī)無法搞定

            • 大數(shù)據(jù)計(jì)算
          • IO密集型

            • CPU經(jīng)常在等待IO
            • 比如網(wǎng)絡(luò)爬蟲
            • 選擇1:多協(xié)程 coroutine
            • 選擇2:多線程 threading
          • CPU密集型

            • 計(jì)算密集型,CPU計(jì)算為主
            • 比如加密解密
            • 使用多進(jìn)程multithreading

          線程池和進(jìn)程池

          • 原理:提前創(chuàng)建好線程/進(jìn)程放在池子里,新的task到來可以重用這些資源,減少了新建、終止線程/進(jìn)程的開銷

          • 池化的好處

            • 提升性能:因?yàn)闇p去了大量新建、終止線程的開銷,重用了線程資源
            • 適用場景:適合處理突發(fā)性大量請求或需要大量線程完成任務(wù)、但實(shí)際任務(wù)處理時(shí)間較短
            • 防御功能:能有效避免系統(tǒng)因?yàn)閯?chuàng)建線程過多,而導(dǎo)致系統(tǒng)負(fù)荷過大響應(yīng)變慢等問題
            • 代碼簡潔:使用線程池的語法比自己新建線程執(zhí)行線程更加簡潔

          全局解釋器鎖GIL

          任何時(shí)刻僅有一個(gè)線程在執(zhí)行。

          在多核心處理器上,使用 GIL 的解釋器也只允許同一時(shí)間執(zhí)行一個(gè)線程

          GIL目的:為了解決多線程之間數(shù)據(jù)完整性和狀態(tài)同步問題

          GIL帶來的問題

          • 即使使用了多線程,同一時(shí)刻也只有單個(gè)線程使用CPU,導(dǎo)致多核CPU的浪費(fèi)
          • GIL只會(huì)對CPU密集型的程序產(chǎn)生影響
          • 如果程序主要是在做I/O操作,比如處理網(wǎng)絡(luò)連接,那么多線程技術(shù)常常是一個(gè)明智的選擇

          規(guī)避GIL的方法

          • 規(guī)避方法2:使用multiprocessing多進(jìn)程,對CPU密集型計(jì)算,單獨(dú)啟動(dòng)子進(jìn)程解釋器去執(zhí)行
          • 規(guī)避方法2:?將計(jì)算密集型的任務(wù)轉(zhuǎn)移到C語言中,因?yàn)镃語言比Python快得多,注意要在C語言中自己釋放GIL

          多線程編程

          應(yīng)用于IO密集型計(jì)算,比如幾乎所有的網(wǎng)絡(luò)后臺服務(wù)、網(wǎng)絡(luò)爬蟲

          引入模塊

          from?threading?import?Thread

          新建、啟動(dòng)、等待結(jié)束

          ????t=Thread(target=func,?args=(100,?))
          ????t.start()
          ????t.join()

          數(shù)據(jù)通信

          import?queue
          q?=?queue.Queue()
          q.put(item)
          item?=?q.get()

          線程安全加鎖

          from?threading?import?Lock
          lock?=?Lock()
          with?lock:
          ????#?do?something

          信號量限制并發(fā)

          from?threading?import?Semaphore
          semaphre?=?Semaphore(10)
          with?semaphre:
          ????#?do?something

          使用線程池

          from?concurrent.futures?import?ThreadPoolExecutor

          with?ThreadPoolExecutor()?as?executor:
          ????#?方法1
          ????results?=?executor.map(func,?[1,2,3])

          ????#?方法2
          ????future?=?executor.submit(func,?1)
          ????result?=?future.result()

          多進(jìn)程編程

          應(yīng)用于CPU密集型計(jì)算,只有發(fā)現(xiàn)多線程編程有性能問題時(shí),才求助于該模塊

          引入模塊

          from?multiprocessing?import?Process

          新建、啟動(dòng)、等待結(jié)束

          p?=?Process(target=f,?args=('bob',))
          p.start()
          p.join()

          數(shù)據(jù)通信

          from?multiprocessing?import?Queue
          q?=?Queue()
          q.put([42,?None,?'hello'])
          item?=?q.get()

          線程安全加鎖

          from?multiprocessing?import?Lock
          lock?=?Lock()
          with?lock:
          ????#?do?something

          信號量限制并發(fā)

          from?multiprocessing?import?Semaphore
          semaphore?=?Semaphore(10)
          with?semaphore:
          ????#?do?something

          進(jìn)程池

          from?concurrent.futures?import?ProcessPoolExecutor

          with?ProcessPoolExecutor()?as?executor:
          ????#?方法1
          ????results?=?executor.map(func,?[1,2,3])

          ????#?方法2
          ????future?=?executor.submit(func,?1)
          ????result?=?future.result()

          多協(xié)程編程

          異步編程的威力

          • Nginx作為 Web 服務(wù)器:打敗了 同步阻塞服務(wù)器 Apache, 使用更少的資源支持更多的并發(fā)連接,體現(xiàn)更高的效率,能夠支持高達(dá) 50,000 個(gè)并發(fā)連接數(shù)的響應(yīng),使用 epoll and kqueue 作為開發(fā)模型
          • Redis為什么這么快:處理網(wǎng)絡(luò)請求采用單線程+使用多路I/O復(fù)用模型,非阻塞IO ,避免了不必要的上下文切換和競爭條件,也不存在多進(jìn)程或者多線程導(dǎo)致的切換而消耗 CPU,不用去考慮各種鎖的問題,不存在加鎖釋放鎖操作,沒有因?yàn)榭赡艹霈F(xiàn)死鎖而導(dǎo)致的性能消耗;
          • Node.js的優(yōu)勢:采用事件驅(qū)動(dòng)、異步編程,為網(wǎng)絡(luò)服務(wù)而設(shè)計(jì)。其實(shí)Javascript的匿名函數(shù)和閉包特性非常適合事件驅(qū)動(dòng)、異步編程 Node.js非阻塞模式的IO處理帶來在相對低系統(tǒng)資源耗用下的高性能與出眾的負(fù)載能力,非常適合用作依賴其它IO資源的中間層服務(wù)
          • Go語言的一個(gè)優(yōu)勢:Go 使用Goroutine 和 channel為生成協(xié)程和使用信道提供了輕量級的語法,使得編寫高并發(fā)的服務(wù)端軟件變得相當(dāng)容易,很多情況下完全不需要考慮鎖機(jī)制以及由此帶來的各種問題,相比Python單個(gè) Go 應(yīng)用也能有效的利用多個(gè) CPU 核,并行執(zhí)行的性能好

          異步編程的原理

          • 核心原理1:超級循環(huán)

            • 在單線程內(nèi)實(shí)現(xiàn)并發(fā)
            • 用一個(gè)超級循環(huán)(其實(shí)就是while true)循環(huán),里面每次輪詢處理所有的task
            • 記憶口訣:《the one loop》至尊循環(huán)馭眾生、至尊循環(huán)尋眾生、至尊循環(huán)引眾生、普照眾生欣欣榮
          • 核心原理2:IO多路復(fù)用

            • select

            • poll

            • epool

            • 數(shù)據(jù)結(jié)構(gòu):bitmap
            • 最大連接數(shù):1024
            • fd拷貝:每次調(diào)用select拷貝
            • 工作效率:輪詢O(N)
            • 數(shù)據(jù)結(jié)構(gòu):數(shù)組
            • 最大連接數(shù):無上限
            • fd拷貝:每次調(diào)用poll拷貝
            • 工作效率:輪詢O(N)
            • 數(shù)據(jù)結(jié)構(gòu):紅黑樹
            • 最大連接數(shù):無上限
            • fd拷貝:fd首次調(diào)用epool_ctl拷貝,每次調(diào)用epoll_wait不拷貝
            • 工作效率:回調(diào)O(1)
            • 是一種同步IO模型,實(shí)現(xiàn)一個(gè)線程可以監(jiān)視多個(gè)文件句柄;
            • 一旦某個(gè)文件句柄就緒,就能夠通知應(yīng)用程序進(jìn)行相應(yīng)的讀寫操作;
            • 沒有文件句柄就緒時(shí)會(huì)阻塞應(yīng)用程序,交出cpu
            • 多路是指網(wǎng)絡(luò)連接,復(fù)用指的是同一個(gè)線程
            • 原理

            • 3種實(shí)現(xiàn)方式

          Python官方異步庫:asyncio

          代碼例子

          ?import?asyncio

          ????#?獲取事件循環(huán)
          ????loop?=?asyncio.get_event_loop()

          ????#?定義協(xié)程
          ????async?def?myfunc(url):
          ????????await?get_url(url)

          ????#?創(chuàng)建task列表
          ????tasks?=?[loop.create_task(myfunc(url))?for?url?in?urls]

          ????#?執(zhí)行爬蟲事件列表
          ????loop.run_until_complete(asyncio.wait(tasks))
          • 優(yōu)點(diǎn):

            • 官方庫支持
            • 明確使用asyncio、await關(guān)鍵字編程,直觀易讀
          • 缺點(diǎn):

            • 很多庫不支持,比如requests

          Python第三方異步庫:Gevent

          代碼例子

          ?import?gevent.monkey

          ????gevent.monkey.patch_all()

          ????import?gevent
          ????import?blog_spider
          ????import?time

          ????begin?=?time.time()
          ????for?url?in?blog_spider.urls:
          ????????blog_spider.craw(url)
          ????end?=?time.time()
          ????print("single?thread,?cost?=?",?end?-?begin)

          ????begin?=?time.time()
          ????tasks?=?[gevent.spawn(blog_spider.craw,?url)?for?url?in?blog_spider.urls]
          ????gevent.joinall(tasks)
          ????end?=?time.time()
          ????print("gevent,?cost?=?",?end?-?begin)
          • 原理

            • 提供猴子補(bǔ)丁MonkeyPatch方法,通過該方法gevent能夠 修改標(biāo)準(zhǔn)庫里面大部分的阻塞式系統(tǒng)調(diào)用,包括socket、ssl、threading和?select等模塊,而變?yōu)閰f(xié)作式運(yùn)行
          • 優(yōu)點(diǎn)

            • 只需要monkey.patch_all(),就能自動(dòng)修改阻塞為非阻塞
            • 提供了pywsgi異步服務(wù)器可以封裝flask
          • 缺點(diǎn)

            • 不知道它具體patch了哪些庫修改了哪些模塊、類、函數(shù)
            • 創(chuàng)造了“隱式的副作用”,如果出現(xiàn)問題很多時(shí)候極難調(diào)試

          Gevent改造Flask為異步服務(wù)

          代碼例子

          from?gevent?import?monkey

          monkey.patch_all()

          from?flask?import?Flask
          from?gevent?import?pywsgi

          app?=?Flask(__name__)


          @app.route("/")
          def?index():
          ????return?"success"


          if?__name__?==?"__main__":
          ????#?app.run()
          ????server?=?pywsgi.WSGIServer(("0.0.0.0",?8888),?app)
          ????server.serve_forever()



          瀏覽 96
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩精品日韩毛片无码 | 操B无码| 91丨九色丨国产在线 | 国产免费激情片 | 99青娱乐|