装飾付きPythonでの簡略化されたマルチプロセス、マルチスレッド同時(装飾同時-Pythonマルチスレッド、プロセス神器)


マルチスレッド、マルチプロセス、コヒーレンスの基本原理概念、およびPythonにおける基本的な実現方法.筆者の前に書いた文章を見てください.トランスポートゲート-Phythonでのプロセス理解(Process),スレッド(Thread)とコヒーレンス(Coroutines)の悟り
ウィスコンシン大学マディソン校のAlex ShermanとPeter Den Hartogはdecoと呼ばれる新しい興味深いPythonマルチプロセッサパッケージを編纂した.
これはPythonでコードを同時に実行するための簡略化された方法である.CPythonグローバル解釈ロックのため、Pythonのコンカレントコードを実行するには、現在、複数の独立したプロセスを使用し、それらの関数呼び出しとパラメータをシーケンス化し、パイプ化する必要があります.
deco論文paper:DECO:Polishing Python Parallel Programmingコード:https://github.com/alex-sherman/deco基本的な使用とインストールのチュートリアルはReadmeを参照してください.md
このライブラリはPydronと呼ばれるものに基づいており、2016年にはこのプロジェクトが研究であり、当時コードは発表されていなかったという人もいます.
関数に簡単な装飾器を使用する以外に、最大の違いはdecoであり、それは本当に簡単で、サブプロセス呼び出しの結果をどのように収集するかにも厳しい制限がある.
decoでは、pythonなどのキーインデックスを持つ可変オブジェクトdictを入力します.python listも可変ですが、インデックスはありません.処理情報を取得できるのはmylist.append().
「しかし、DECOは確かにプログラムに重要な制限を加えています.すべての突然変異はインデックスにしか基づいていません.」
まず、decoがどのように動作するかを理解する基本的な例を見てみましょう.
@concurrent   #Identify the concurrent function
def do_work(key):
  return some_calculations(...)

data = {}
@synchronized
def run():
  for key in data:
    data[key] = do_work(key)
  print data # data will be automatically synchronized here


プログラマーの唯一の介入は、2つのアクセサリー@concurrentと@synchronizedを挿入することです.@concurrentでは、識別子と@synchronized装飾タグの機能を並列に実行する関数を考えています.ここで、同時機能が呼び出されます.
なぜdecoが強いのか、本当の理由はこうです.
コンカレント関数のパラメータを変更し、変更した内容を親プロセスに同期できます.これはPythonのmultiprocessとは違います.pool、後者は、コンカレント関数から変更されたステータスを返し、パラメータの変更を破棄する必要があります.たとえば、経度範囲の辞書を持ち、指定した範囲の平均温度を計算し、範囲のキーを更新する@concurrent関数を呼び出すことができます.ループで関数を呼び出し、その関数を呼び出すたびに辞書の一意のキーを更新すると、計算は並列に行われ、親のデータにアクセスする前に、各プロセスの結果処理が自動的に同期されます(@synchronizedデザイナは処理できます).
上記の例では、コンカレント関数呼び出しの結果をインデックスまたはキーオブジェクト(リストおよび辞書)に割り当て、パラレル呼び出しが完了した後、親プロセスでデータにアクセスする前にこれらの場所に同期できます.再び,@synchronized装飾器を可能にし,この装飾器は実際に親関数体内の割り当てを書き換え,それらが同時に発生し,後で同期することを可能にした.
実際にマルチプロセスフルテンプレートを使用するには、次の手順に従います.
import deco
import time
import random
from collections import defaultdict


@deco.concurrent(processes=16) 
def process_lat_lon(lat, lon, data):
    """
    We add this for the concurrent function
    :param lat: 
    :param lon: 
    :param data: 
    :return: 
    """
    time.sleep(0.1)
    return data[lat + lon]


@deco.synchronized  
def process_data_set(data):
    """
    And we add this for the function which calls the concurrent function
    :param data: 
    :return: 
    """
    results = defaultdict(dict)
    for lat in range(10):
        for lon in range(10):
            results[lat][lon] = process_lat_lon(lat, lon, data)
    return dict(results)


if __name__ == "__main__":
    """Windows    __main__   ,      ,         """
    random.seed(0)
    data = [random.random() for _ in range(200)]
    start = time.time()
    print(process_data_set(data))
    print(time.time() - start)

実際にマルチスレッドフルテンプレートを使用するには、次の手順に従います.
import deco
import time
import random
from collections import defaultdict


@deco.concurrent.threaded(processes=16)
def process_lat_lon(lat, lon, data):
    """
    We add this for the concurrent function
    :param lat:
    :param lon:
    :param data:
    :return:
    """
    time.sleep(0.1)
    return data[lat + lon]


@deco.synchronized
def process_data_set(data):
    """
    And we add this for the function which calls the concurrent function
    :param data:
    :return:
    """
    results = defaultdict(dict)
    for lat in range(10):
        for lon in range(10):
            results[lat][lon] = process_lat_lon(lat, lon, data)
    return dict(results)


if __name__ == "__main__":
    """Windows    __main__   ,      ,         """
    random.seed(0)
    data = [random.random() for _ in range(200)]
    start = time.time()
    print(process_data_set(data))
    print(time.time() - start)