python 多線程,多進程的快速實現 concurrent, joblib, multiprocessing, threading

python 多線程,多進程的快速實現 concurrent, joblib, multiprocessing, threading

Python 界有條不成文的準則: 計算密集型任務適合多進程,IO 密集型任務適合多線程。

通常來說多線程相對于多進程有優勢,因為創建一個進程開銷比較大,然而因為在 python 中有 GIL 這把大鎖的存在,導致執行計算密集型任務時多線程實際只能是單線程。而且由于線程之間切換的開銷導致多線程往往比實際的單線程還要慢,所以在 python 中計算密集型任務通常使用多進程,因為各個進程有各自獨立的 GIL,互不干擾。

而在 IO 密集型任務中,CPU 時常處于等待狀態,操作系統需要頻繁與外界環境進行交互,如讀寫文件,在網絡間通信等。在這期間 GIL 會被釋放,因而就可以使用真正的多線程。

本文主要介紹一下如何使用python 快速實現多進程及多線程:

多進程

multiprocessing

from multiprocessing import Pool
def asy(sub_f):
    with Pool(processes=6) as p:
        result = []
        for j in range(6):
            a = p.apply_async(sub_f, args=(j,))
            result.append(a)
        res = [j.get() for j in result]
        
def mp(sub_f):
    with Pool(processes=6) as p:
        res = p.map(sub_f, list(range(6)))
    return
  

joblib

from joblib import Parallel, delayed, parallel_backend

def joblib_process(sub_f):
    with parallel_backend("multiprocessing", n_jobs=6):
        res = Parallel()(delayed(sub_f)(j) for j in range(6))
    return

concurrent

from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
def process_pool(sub_f):
    with ProcessPoolExecutor(max_workers=6) as executor:
        res = executor.map(sub_f, list(range(6)))

實現

def showtime(f, sub_f, name):
    start_time = time.time()
    f(sub_f)
    print("{} time: {:.4f}s".format(name, time.time() - start_time))

def main(sub_f):
    showtime(normal, sub_f, "normal")
    print()
    print("------ 多進程 ------")
    showtime(joblib_process, sub_f, "joblib multiprocess")
    showtime(mp, sub_f, "pool")
    showtime(asy, sub_f, "async")
    showtime(process_pool, sub_f, "process_pool")
    print()

多線程

joblib

def joblib_thread(sub_f):
    with parallel_backend('threading', n_jobs=6):
        res = Parallel()(delayed(sub_f)(j) for j in range(6))
    return

thread

def thread(sub_f):
    threads = []
    for j in range(6):
        t = Thread(target=sub_f, args=(j,))
        threads.append(t)
        t.start()
    for t in threads:
        t.join()

Thread pool

from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor

def thread_pool(sub_f):
    with ThreadPoolExecutor(max_workers=6) as executor:
        res = [executor.submit(sub_f, j) for j in range(6)]

實現

print("----- 多線程 -----")
    showtime(joblib_thread, sub_f, "joblib thread")
    showtime(thread, sub_f, "thread")
    showtime(thread_pool, sub_f, "thread_pool")
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容