Python学習【365日チャレンジ!】224日目のマスターU(@Udemy11)です。
暑い暑いと言っていたのに、ここ数日で一気に朝晩が冷え込むようになりました。
ほんと最近の天候ってどうなってるんでしょうか?
涼しいのを通り越して寒いと感じるんですから、ほんとびっくりです。
個人的には、暑いより寒いほうがいいのですが、寒いより涼しいのほうがうれしいのは私だけではないですよね。
それでは、今日もPython学習をはじめましょう。
昨日の復習
昨日は、map_async
とimap
を使っての非同期処理を学習しました。
Pool
を使ったmap
では、並列処理はできましたが、非同期処理にはなっていませんでした。
同じ処理を非同期で行うことができるのがmap_async
とimap
でした。
imap
を使うとイテラブルオブジェクトが生成されるので、その中からデータを取り出して出力するために、リスト内包表記のfor
ループを使いました。
くわしくは、昨日の記事をごらんください。
今日は、プロセス間通信について学習します。
スレッドとの違い
マルチスレッドの場合は、メモリを共有していたので、スレッド間のデータのやり取りが簡単でした。
プロセスの場合は、それぞれのプロセスが使うメモリが別々なので、ひと工夫必要になってきます。
スレッド間通信については、こちらの記事でおさらいしておきましょう。
スレッドの復習
まずは、スレッドのメモリ共有について、少し戻ってマルチスレッドのコードを復習してみます。
import logging
import threading
logging.basicConfig(level=logging.DEBUG, format='%(threadName)s: %(message)s')
def worker1(d, lock):
with lock:
i = d['x']
d['x'] = i + 1
logging.debug(d)
def worker2(d, lock):
with lock:
i = d['x']
d['x'] = i + 1
logging.debug(d)
if __name__ == '__main__':
d = {'x': 0}
lock = threading.Lock()
t1 = threading.Thread(target=worker1, args=(d, lock))
t2 = threading.Thread(target=worker2, args=(d, lock))
t1.start()
t2.start()
t1.join()
t2.join()
logging.debug(d)
Thread
とLock
を使ってスレッド間で辞書型データのd
を共有して操作しています。
実行結果
Thread-1: {'x': 1}
Thread-2: {'x': 2}
MainThread: {'x': 2}
d
は、メインスレッドと2つのスレッド間で共有されているので、最初value
が0
でしたが、16行目と27行目の出力では、9行目と15行目で1
ずつプラスされて2
に増えています。
プロセス間通信
続いてプロセスで同じことを実行してみます。
import logging
import multiprocessing
logging.basicConfig(level=logging.DEBUG, format='%(processName)s: %(message)s')
def worker1(d, lock):
with lock:
i = d['x']
d['x'] = i + 1
logging.debug(d)
def worker2(d, lock):
with lock:
i = d['x']
d['x'] = i + 1
logging.debug(d)
if __name__ == '__main__':
d = {'x': 0}
lock = multiprocessing.Lock()
t1 = multiprocessing.Process(target=worker1, args=(d, lock))
t2 = multiprocessing.Process(target=worker2, args=(d, lock))
t1.start()
t2.start()
t1.join()
t2.join()
logging.debug(d)
実行結果
Process-1: {'x': 1}
Process-2: {'x': 1}
MainProcess: {'x': 0}
Lock
はプロセスでも使えるので、threading.Thread
をmultiprocessing.Process
に変更しています。
もちろん、最初のインポートをmultiprocessing
に変えて、ロギングのthreadName
をprocessName
に変更しています。
実行結果は、メインプロセスのd
は、最初に定義した値のままで、他の2つのプロセスは1
になっています。
スレッドと違い、プロセスの場合は、それぞれのプロセスで別々のメモリを使っているので、それぞれのプロセスで別々の変数d
が作成されます。
同じ変数名でも別々のものということですね。
違いを踏まえて
スレッドとプロセスの違いを理解できたでしょうか?
プロセスにもスレッドと同じように、データを共有する方法もあるわけですが、まずは、プロセスとスレッドの違いを理解した上で、明日からプロセス間通信のコードを学んでいきましょう。
それでは明日もGood Python!