簡體   English   中英

在Python和Eventlet中使用多個核心

[英]Using multiple cores with Python and Eventlet

我有一個Python Web應用程序,客戶端( Ember.js )通過WebSocket與服務器通信(我正在使用Flask-SocketIO )。 除了WebSocket服務器之外,后端還有兩件值得提及的事情:

當客戶端提交圖像時,在數據庫中創建其實體,並將id放入圖像轉換隊列中。 工人抓住它並進行圖像轉換。 之后,工作人員將其放入OCR隊列,在那里它將由OCR隊列工作者處理。

到現在為止還挺好。 WS請求在不同的線程中同步處理(Flask-SocketIO使用Eventlet),並且繁重的計算操作異步發生(在單獨的線程中也是如此)。

現在問題是:整個應用程序在Raspberry Pi 3上運行。 如果我沒有使用它的4核,我只有一個主頻為1.2 GHz的ARMv8內核 這對於OCR來說是非常小的力量。 所以我決定了解如何在Python中使用多個內核。 雖然我讀到了GIL的問題但是我發現了多處理 ,它說The multiprocessing package offers both local and remote concurrency, effectively side-stepping the Global Interpreter Lock by using subprocesses instead of threads. 正是我想要的。 所以我立即取代了

from threading import Thread
thread = Thread(target=heavy_computational_worker_thread)
thread.start()

通過

from multiprocessing import Process
process = Process(target=heavy_computational_worker_thread)
process.start()

隊列需要由多個核心處理,所以我不得不改變

from queue import Queue
queue = multiprocessing.Queue()

import multiprocessing
queue = multiprocessing.Queue()

同樣。 有問題:隊列和線程庫由Eventlet進行猴子修補 如果我停止使用Monkey修補版本的Thread和Queue並使用multiprocsssing那個版本,那么在訪問隊列時,Eventlet啟動的請求線程將永遠阻塞。

現在我的問題:

有什么辦法可以讓這個應用程序在單獨的核心上進行OCR和圖像轉換嗎?

如果可能的話,我想繼續使用WebSocket和Eventlet。 我的優點是進程之間唯一的通信接口是隊列。

我已經擁有的想法: - 不使用隊列的Python實現,而是使用I / O. 例如,不同子進程可以訪問的專用Redis - 更進一步:將每個隊列工作者作為單獨的Python進程啟動(例如python3 wsserver | python3 ocrqueue | python3 imgconvqueue)。 然后我必須確保自己對隊列和數據庫的訪問是非阻塞的

但最好的辦法是保持單個進程並使其與多處理一起工作。

非常感謝你提前

Eventlet當前與多處理包不兼容。 這項工作有一個未解決的問題: https//github.com/eventlet/eventlet/issues/210

我認為在您的情況下運行良好的替代方法是使用Celery來管理您的隊列。 Celery將啟動一個工作進程池,等待主進程通過消息隊列提供的任務(同時支持RabbitMQ和Redis)。

Celery工作者不需要使用eventlet,只需要使用主服務器,因此這可以讓他們在沒有eventlet強加的限制的情況下做任何他們需要做的事情。

如果您有興趣探索這種方法,我有一個完整的例子使用它: https//github.com/miguelgrinberg/flack

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM