Python マルチプロセス imap

Python学習【365日チャレンジ!】223日目のマスターU(@Udemy11)です。

私が住んでいるところは結構田舎だという認識はあるのですが、先日、そんな私でもびっくりすることがありました。

それが、イノシシ!

イノシシ

そんなに山道でもないのですが、ちょっと小高い丘の道を通っていると、結構でかいイノシシが道のど真ん中にいてめっちゃびっくりしました。

幸い車に向かって突っ込んで来なかったので、こちらもあちらも被害はありませんでしたが、思い出すたびに冷や汗が出ます。

それでは、今日もPython学習をはじめましょう。

昨日の復習

昨日は、プロセスのコードの短縮化ができるmapを学習しました。

プロセスの並列処理とブロックをあわせた使い方ができるmapで、複数のコードが必要な複数のプロセスを1行のコードにすることができました。

非同期処理ではないので、次の行の処理はmapの処理が済んでから実行されました。

詳しくは昨日の記事をごらんください。

今日は、map-asyncimapを使った非同期処理について学習します。

map_async

mapは非同期処理ではありませんでしたが、map_asyncは非同期の並列処理をすることができます。

import logging
import multiprocessing
import time

logging.basicConfig(
    level=logging.DEBUG, format='%(processName)s: %(message)s'
)

def worker1(i):
    logging.debug('start')
    time.sleep(5)
    logging.debug('end')
    return i

if __name__ == '__main__':
    with multiprocessing.Pool(3) as p:
        r = p.map_async(worker1,[100, 200, 300])
        logging.debug('executed')
        logging.debug(r.get())

昨日のコードの17行目をmapからmap_asyncに変えて、19行目のrr.get()に変えただけです。

実行結果

MainProcess: executed
ForkPoolWorker-1: start
ForkPoolWorker-2: start
ForkPoolWorker-3: start
ForkPoolWorker-1: end
ForkPoolWorker-3: end
ForkPoolWorker-2: end
MainProcess: [100, 200, 300]

非同期処理なので、最初にメインプロセスのexecutedが出力されています。

あとは、昨日の出力と同じで、executedの出力が最初か後かという違いですね。

imap

続いて、imapを使った実行をしてみましょう。

if __name__ == '__main__':
    with multiprocessing.Pool(3) as p:
        r = p.imap(worker1,[100, 200, 300])
        logging.debug('executed')
        logging.debug([i for i in r])

imapを使った場合、rがイテレーターオブジェクトになるので、19行目でリスト内包表記を使ってforループで出力しています。

通常のforループで表記すると次のようになります。

        for i in r:
            logging.debug(i)

実行結果はどちらも最初の結果と同じになります。

こんがらがる

昨日も書きましたが、ほんと似たような処理で違いがたくさん出てくるので、頭がこんがらがってきます。

人間って自分の理解を超えると眠くなるようで、学習しながら、ウトウトしてしまいました。

パソコンに向かってウトウトしてしまって何が困るかというと、知らない間に変な文字が入力されていたり、永遠と同じ文字をタイプしてしまっていたりと自分で把握できないミスが起こってしまいます。

そんなことにならないように、しっかりと睡眠をとって、頭がスッキリした状態でPythonを学習するようにしましょう!

それでは明日も、Good Python!