我目前正在调查Celery用于视频处理后端。基本上我的问题如下:
鉴于第3点,我需要在整个过程中维护和更新框架的有序结构,并将此结构的子部分的农场计算提供给Celery工作人员。最初,我考虑如下组织事情:
[frontend server] -stream-> [celery worker 1 (greenlet)] --> [celery worker 2 (prefork)]
这个想法是celery worker 1
执行长期运行的主要是I / O绑定的任务。从本质上讲,这些任务仅执行以下操作:
collections.deque
对象,如目前所示)。任何CPU绑定操作(即图像分析)都会发送到celery worker 2
。
我想将协程执行为一项任务,以便我可以yield
执行长期运行的任务,以便不阻止celery worker 1
的操作。换句话说,我希望能够做类似的事情:
def coroutine(func):
@wraps(func)
def start(*args, **kwargs):
cr = func(*args, **kwargs)
cr.next()
return cr
return start
@coroutine
def my_taks():
stream = deque() # collections.deque
source = MyAsynchronousInputThingy() # something i'll make myself, probably using select
while source.open:
if source.has_data:
stream.append(Frame(source.readline())) # read data, build frame and enqueue to persistent structure
yield # cooperatively interrupt so that other tasks can execute
有没有办法让基于协程的任务无限期地运行,理想情况下会产生yield
的结果?
答案 0 :(得分:3)
Eventlet背后的主要思想是你要编写同步代码,就像使用线程一样,socket.recv()
应该阻止当前线程直到下一个语句。这种风格在调试时非常容易阅读,维护和推理。为了使事情变得有效和可扩展,在幕后,Eventlet可以用绿色线程和epoll / kqueue / etc机制替换看似阻塞的代码,以便在适当的时间唤醒那些绿色线程。
所以你需要的只是尽快执行eventlet.monkey_patch()
(例如模块中的第二行)并确保在MyInputThingy
中使用纯Python套接字操作。忘记异步,只需像编写线程一样编写普通的阻塞代码。
Eventlet使同步代码再次良好。