Pythonの高度なマルチスレッド化とマルチプロセス(継続的な更新)

Pythonスレッドには典型的な問題であるGIL(グローバルコントロールロック、つまり、Pythonが特定の時間に実行できるスレッドは1つだけです)があるので、マルチスレッド化はどのように行われますか?実装?

回答:I / O集中型のタスクの処理では、リクエストを待機すると、PythonのI / O関数が自動的にGILを解放してスレッドを実行するため、I / O時間が短縮されます。これは、並行処理です。実装メソッドには、concurrent.futureモジュール(futures.ThreadPoolExecutorクラス)とスレッドモジュールが含まれます。

Pythonは真の並列処理を実現できますか?マルチプロセスとは一体何ですか?複数のプロセスはより速くなりますか?

回答:これで結構です並列タスクを実行するCPUの数を選択できるので、マルチプロセスタスクを実行できます。マルチプロセスの並列処理は、マルチスレッドよりも高速である必要はありません。2つのアプリケーションフィールドは異なります。マルチプロセスは、CPU集中型(多数の数値計算、すべて実行中のメモリ内)操作に適しており、マルチスレッドはI / O集中型(およびディスクにはインタラクティブな動作)があります。実装メソッドには、スレッド化モジュール、mutiprocessingモジュール、futures.ProcessPoolExecutorクラスが含まれます。

 最初にマルチスレッディングを実装しましょう、それはより簡単に思えます。

In [65]: import requests

In [66]: import tqdm

In [67]: import os

In [68]: import time

In [69]: import sys

In [70]: POP_CC= ('CC,IN,US,ID,BP').split()

In [71]: BASE_URL = 'http://flupy.org/data/flags'

In [72]: DEST_DIR = 'downloads/'

In [73]: def save_flag(img,filename):
    ...:     path = os.path.join(DEST_DIR,filename)
    ...:     with open(path,'wb') as fp:
    ...:         fp.write(img)
    ...:

In [74]: def get_flag(cc):
    ...:     url = '{}/{cc}/{cc}.gif'.format(BASE_URL,cc=cc.lower())
    ...:     resp = requests.get(url)
    ...:     return resp.content
    ...:

In [75]: def show(text):
    ...:     print(text,end='')
    ...:     sys.stdout.flush()
    ...:

In [76]: def download_one(cc): # 技巧,所有基操都放在一个里
    ...:     image = get_flag(cc)
    ...:     show(cc)
    ...:     save_flag(image,cc.lower()+'.gif')
    ...:     return cc
    ...:

In [77]: MAX_WORKERS = 20 # 20个线程

In [78]: def download_many(cc_list):
    ...:     workers = min(MAX_WORKERS,len(cc_list)) # 任务少的话开多没用
    ...:     with futures.ThreadPoolExecutor(workers) as executor:
    ...:         res = executor.map(download_one,tqdm.tqdm(sorted(cc_list))) # 其实经历了future实例的过程,可以细究,不过单纯实现不需要知道,tqdm显示进度条
    ...:     return len(list(res))
    ...:

In [79]: def main(download_many):
    ...:     t0 = time.time()
    ...:     count = download_many(POP_CC)
    ...:     elapsed = time.time()-t0
    ...:     msg = '\n{} flags downloaded in {:.2f}s'
    ...:     print(msg.format(count,elapsed))
    ...:

In [80]: if __name__ == 'main':
    ...:     main(download_many)

 

おすすめ

転載: blog.csdn.net/weixin_40539952/article/details/107488111