pythonのmultiprocessing.Queueとqueue.Queueの違い
Queueというとpythonには3つのQueueが存在します.
multiprocessing.Queue
queue.Queue
asyncio.Queue
asyncio.Queue
は get()
がコルーチンであることから明らかに違います.またthread-safe/process-safeではありません
queue.Queue
はthread safeであり,thread間のやり取りには使えますがprocess間では使えません.
multiprocessing.Queue
はthread safeかつprocess-safeでprocess間のやり取りにも使えます.
万物に multiprocessing.Queue
を使えば良いように思えますが, multiprocessing.Queue
はpickle可能オブジェクトしか使うことができません.
この注意からわかるように multiprocessing.Queue
は pickleを内部的に叩いています.
正確にはpipeを作成し,pickleをbyteでやりとりをしています.
一方で, queue.Queue
は同一thread上のため参照をリストにいれているような実装になっています
このため,multiprocessing.Queue
で大きいobjectなどをやりとりするとpickleにたいしオーバーヘッドが発生します.
このまえ少し書いたqita 学習時のバッチデータのio待ちをマルチプロセスにして簡単に早くする - Qiita で述べたオーバーヘッドとはこのことです.
multiprocessing.Queue 14.872217274998548 queue.Queue 0.016910205013118684
import numpy as np import multiprocessing as mp import queue import asyncio import timeit arr = np.random.random((1000, 1000)) def mp_queue(): q = mp.Queue() q.put(arr) q.get() def queue_queue(): q = queue.Queue() q.put(arr) q.get() print('multiprocessing.Queue') print(timeit.timeit(mp_queue, number=1000)) print() print('queue.Queue') print(timeit.timeit(queue_queue, number=1000)) print()
chainerやdeepなどをマルチプロセスで呼び出している場合, multiprocess.Queue().get()
を叩くことになり大きいデータの場合オーバーヘッドが発生します.
気になる方はthreadも用い, 別プロセスで読み込んだデータを multiprocess.Queue()
から queue.Queue()
に一旦移し替えるのが良いと思われます.
python 3.6ではこのあたりをいい感じに書けそうなasync generatorが来るそうなのでちょっと楽しみです.(使わなくてもasyncioが使えるとそこそこきれいに書けますたぶん)
archlinuxからcupsでbrother hl-l2365dwを使いたい
やりたいこと
TL;DR
やったこと
$ yaourt -S cups $ sudovim /etc/cups-files.conf SystemGroup sys root ↓ SystemGroup wheel root $ systemctl start org.cups.cupsd.service $ systemctl enable org.cups.cupsd.service $ yaourt brother-hll2360d $ lpadmin -p brother -E -v "ipp://192.168.xx.xxx/ipp/port1" -P /usr/share/cups/model/brother-HLL2360D-cups-en.pdd続きを読む