我有一个Python应用程序,其中客户机(Ember.js)通过WebSocket与服务器进行通信(我正在使用烧瓶-SocketIO)。除了WebSocket服务器之外,后端还做了两件值得注意的事情:
当客户端提交图像时,它的实体将在数据库中创建,并将id放入图像转换队列中。工作人员抓取它并进行图像转换。之后,工作人员将其放入OCR队列中,由OCR队列工作人员处理。
到目前一切尚好。WS请求在单独的线程中同步处理(Flask为此使用Eventlet ),而繁重的计算操作也是异步进行的(也是在单独的线程中)。
现在的问题是:整个应用程序运行在一个Raspberry Pi 3上。如果我不使用这4个核心,它只有一个,一个ARMv8内核,时钟为1.2 GHz。这对于OCR来说是很小的能量。所以我决定找出如何用Python来使用多个核心。虽然我读到了有关吉尔的问题),但我还是发现了多处理的地方,上面写着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编写的猴补丁。如果我停止使用猴子补丁版本的线程和队列,而是使用来自multiprocsssing的版本,那么在访问队列时,由Eventlet启动的请求线程将永远阻塞。
现在我的问题是:
有什么方法可以让这个应用程序在一个单独的核心上进行OCR和图像转换吗?
如果可能的话,我想继续使用WebSocket和Eventlet。我的优势是,进程之间唯一的通信接口将是队列。
我已经有了这样的想法:-不是使用队列的Python实现,而是使用I/O,例如,不同的子进程将访问一个专用的Redis --更进一步:将每个队列工作者作为一个单独的Python进程启动(例如,python3 wsserver \ python3料队列/ python3 img卷积队列)。然后,我必须确保队列和数据库上的访问是非阻塞的。
不过,最好的办法是保留单个进程,并使其与多处理一起工作。
先谢谢你
发布于 2016-10-16 02:07:05
Eventlet当前与多处理包不兼容。对于这项工作,还有一个悬而未决的问题:https://github.com/eventlet/eventlet/issues/210。
我认为,在您的情况下,使用芹菜来管理队列是可行的。芹菜将启动一个工作进程池,等待主进程通过消息队列(RabbitMQ和Redis都支持)提供的任务。
芹菜工人不需要使用eventlet,只有主服务器才能使用,因此这使他们可以自由地做他们需要做的任何事情,而不受eventlet的限制。
如果您有兴趣探索这种方法,我有一个使用它的完整示例:https://github.com/miguelgrinberg/flack。
https://stackoverflow.com/questions/40058748
复制相似问题