クライアント(Ember.js)がWebSocket(私はFlask-SocketIOを使用しています)経由でサーバーと通信するPython Webアプリケーションを持っています。 (tesseract使用)PythonとEventletで複数のコアを使用する
- は、クライアントから
- OCRの着信画像(graphicsmagickを使用して)いくつかの画像変換を行う: アパートのWebSocketサーバからバックエンドは言及される価値がある2つのことを行います
クライアントがイメージを送信すると、エンティティがデータベースに作成され、IDがイメージ変換キューに格納されます。作業者はそれをつかんで画像変換を行う。その後、作業者はそれをOCRキューに入れ、そこでOCRキュー・ワーカーによって処理されます。
これまでのところとても良いです。 WSリクエストは別々のスレッドで同期して処理されます(Flask-SocketIOではEventletが使用されます)、重い計算アクションは非同期で発生します(別々のスレッドでも同様です)。
問題点:アプリケーション全体がRaspberry Pi 3で実行されています。私が4つのコアを使用していない場合は、1つのARMv8コアが1.2GHzでクロックされているだけです。これはOCRの力はほとんどありません。だから私はPythonで複数のコアを使う方法を見つけることにしました。私はGILの問題について読んだが、multiprocessingについては
The multiprocessing package offers both local and remote concurrency, effectively side-stepping the Global Interpreter Lock by using subprocesses instead of threads.
と出ていた。まさに私が望んでいたもの。だから私は即座にfrom multiprocessing import Process process = Process(target=heavy_computational_worker_thread) process.start()
私は
にimport multiprocessing queue = multiprocessing.Queue()
from queue import Queue queue = multiprocessing.Queue()
を変更しなければならなかったようにも複数のコアで処理されるために必要なキューによって
from threading import Thread thread = Thread(target=heavy_computational_worker_thread) thread.start()
を置き換えます
も同様である。問題:キューとスレッドライブラリは、Eventletによってmonkey patchedです。私が猿のパッチを当てたバージョンのThread and Queueの使用をやめ、代わりに
multiprocsssing
のものを使用すると、キューにアクセスするときにEventletブロックによって開始されたリクエストスレッドが永遠にブロックされます。は今、私の質問:
は、私は、このアプリケーションが別々のコア上のOCRと画像変換を行うことができますどのような方法がありますか?
可能であれば、WebSocketとEventletを使いたいと思います。私が持っている利点は、プロセス間の唯一の通信インターフェイスがキューになることです。
私がすでに持っていたアイデア: - Pythonのキュー実装ではなく、I/Oを使用しています。たとえば、異なるサブプロセスがアクセスする専用のRedis - さらにステップを進める:すべてのキューワーカーを個別のPythonプロセスとして開始する(例:python3 wsserver | python3 ocrqueue | python3 imgconvqueue)。次に、キューとデータベースのアクセスが非ブロックであることを自分自身で確認しなければならないでしょう。
最高のことは、単一プロセスを維持してマルチプロセッシングで動作させることです。
は
私はEvenletライブラリを知らないので、私の答えは当てはまりません。 「メイン」プログラムでマルチスレッドを使用する。そのメインアプリケーションの各「プロセス」内で、サブプロセスを呼び出すために「サブプロセス」を使用します(これは奇妙に思えますが、PythonプログラムはPythonプログラムを呼び出します)。これらのサブプロセスでのみ、 "Eventlet"ライブラリ(またはプロセスセーフでないライブラリ)を使用してください。メインプログラムでは使用しないでください。 「キュー」を使用することはできませんが、ファイルを介してデータを渡すことができます(例:プログラムAはイメージファイルを書き込み、終了し、プログラムBは開始し、このファイルを読み取ります)。 –