經驗拾憶(純手工)=> Python三程

GIL的理解

GIL這個話題至今也是個爭議較多的,對於不用應用場景對線程的需求也就不一樣,說下我聽過的優勢:
1. 我沒有用過其餘語言的多線程,因此沒法比較什麼,可是對於I/O而言,Python的線程仍是比較高效的。
2. 有些第三方基於Python的框架和庫,好比Tensorflow等基於C/C plus plus重寫的Python線程機制。
3. 至於換成Cython編譯器解決GIL,這個只是聽過,沒用過。
4. Python多線程對於web、爬蟲方面也能夠表現出較好的性能。
5. Python多進程是無缺的,能夠把資源消耗較少的非必要線程工做轉爲多進程來工做。
6. 計算密集型就別想多線程了,一概多進程。
7. Python還有細粒度且高效的協程。
8. 若是有N核CPU,那麼同時並行的進程數就是N,每一個進程裏面只有一個線程能搶到工做權限。
   因此同一時刻最大的並行線程數=進程數=CPU的核數(這條個人我的理解很模糊,參考吧)

多線程

多線程有2種經過start的那種方式,很是廣泛,此處就不寫了。
新版線程池 future庫 是python3.2新出的功能(記住這個future)
方式1:(sublime運行後直接貼上來了)
    from time import sleep
    from concurrent.futures import ThreadPoolExecutor,as_completed,ALL_COMPLETED,wait
    
    executor = ThreadPoolExecutor(max_workers=10)        # 初始化線程池10個坑
    def f():
        sleep(15)
        return 100
    all_tasks = [executor.submit(f) for _ in range(10)]  # 提交10個線程,全放池裏執行
    # for per_thread in as_completed(all_tasks):         
        # print(per_thread.result())
    ---------# 注意上面,as_completed(all_tasks) 是等待future對象完成後才執行主線程
    ---------# 注意下面,wait和 as_completed() 的 做用同樣,就和普通版的join() 類似
    for per_thread in all_tasks:
        print(per_thread.result())
    wait(all_tasks, return_when=ALL_COMPLETED)   # 還能夠選FIRST_COMPLETED,待第一個完成後
    print('主線程')
        
方式2: map多線程版
    value_list = executor.map(func, list(range(10))) # 返回的直接是map後的序列
    for value in value_list:
        print(value)
    注意:    
        這個map方式,若是要傳多個參數就涉及到高階函數那節講的偏函數了。

多進程

多進程有2種經過start的那種方式+普通進程池,一樣很是廣泛,此處就不寫了,本身百度一下。
新版進程池 一樣是和上面用同樣的future庫,驚不驚喜。(能夠看出好的程序要向着統一封裝的方向優化)
也許你會驚訝,由於只把thread單詞改成processing就是進程池版本了,就是這麼簡單!!!!!
from time import sleep
import multiprocessing
from concurrent.futures import ProcessPoolExecutor,as_completed,ALL_COMPLETED,wait
executor = ProcessPoolExecutor(max_workers=multiprocessing.cpu_count())
def f():
    sleep(15)
    return 100

if __name__ == '__main__':    # 這句要加
    all_tasks = [executor.submit(f) for _ in range(multiprocessing.cpu_count())]
    for per_thread in as_completed(all_tasks):
        print(per_thread.result())
    # for per_thread in all_tasks:
    #     print(per_thread.result())
    # wait(all_tasks, return_when=ALL_COMPLETED)
    print('主進程')   
# 這就是 futures 模塊 設計思想的魅力

多協程

前言:
    也許你記得,函數用到 yield 來代替 return 就變成了 生成器。其特色是代碼片斷斷點式執行。
    若是有多個yield, 就能夠本身用程序來切換執行程序。(這就是協程的特色)
推薦:(學習中。。。)
    此筆者寫的很好:
    https://juejin.im/post/5ccf0d18e51d453b557dc340
相關文章
相關標籤/搜索