sat*_*oru 3 python asynchronous green-threads eventlet
我正在为数据分析任务编写Web UI.
这是它应该工作的方式:
在用户指定像dataset和之类的参数后learning rate,我创建了一个新的task record,然后异步启动此任务的执行程序(执行程序可能需要很长时间才能运行.),并且用户被重定向到其他页面.
搜索完之后async library for python,我开始了eventlet,这是我在flask视图函数中写的内容:
db.save(task)
eventlet.spawn(executor, task)
return redirect("/show_tasks")
Run Code Online (Sandbox Code Playgroud)
使用上面的代码,执行程序根本不执行.
我的代码可能有什么问题?或许我应该尝试其他的东西?
当您获得直接解决方案时,我将尝试回答您的第一个问题,并解释为什么您的代码无法按预期工作.
披露:我目前维护的是Eventlet.此评论将包含一些简化以适合合理的大小.
有两种方法可以进行多线程和Eventlet漏洞利用协作方法.Greenlet库的核心是基本上允许您创建独立的"执行上下文".可以将这样的上下文视为所有局部变量的冻结状态和指向下一指令的指针.基本上,多线程=上下文+调度程序.Greenlet提供了上下文,因此我们需要一个调度程序,它可以决定哪个上下文应该立即占用CPU.转而,为了做出决定,我们还应该运行一些代码.这意味着一个单独的上下文(绿色线程).这个特殊的绿色线程在Eventlet代码库中称为Hub.调度保持有序集合了需要尽快运行环境的- 运行队列,并设置在等待的东西(如网络IO或时间有限的睡眠)来完成的上下文.
但由于我们正在进行合作多任务处理,因此一个上下文将无限期地执行,除非它明确地产生另一个上下文.这将是非常悲伤的编程风格,并且根据定义与现有的库不兼容(指向他们知道谁); 所以Eventlet所做的是它提供了常见模块的绿色版本,改变了它们切换到Hub而不是阻止所有内容.然后,可能会花费一些时间在其他绿色线程或Hub的wait-for-external-events实现中,在这种情况下Hub将切换回发起该事件的绿色线程 - 并且它将继续执行.
结束.现在回到你的问题.
eventlet.spawn实际上做了什么:它创建了一个新的执行上下文.基本上,在内存中分配一个对象.它还告诉调度程序将此上下文放入运行队列,因此在第一个可能的时刻,Hub将切换到新生成的函数.您的代码没有提供这样的时刻.没有你明确放弃执行其他绿色线程的地方,对于Eventlet,这通常是通过eventlet.sleep().由于您不使用绿色版本的通用模块,因此当其他代码等待时,没有机会隐式生成.最合适的(如果不是唯一的)地方将是你的WSGI服务器的接受循环:它应该给其他绿色线程机会在等待下一个请求时运行.第一个答案中提到的eventlet.monkey_patch()只是用相应的绿色版本替换所有(或子集)通用模块的便捷方式.
对整体设计的不必要的意见
在单独的部分,轻松跳过.当且仅当您正在构建抗错误的软件,你通常要限制产生的线程执行时间(包括但不限于"绿色")和流程,至少报告(日志)或响应其未处理的错误.在提供的代码中,您生成的绿色线程在技术上可能在下一刻或五分钟后运行(同样,因为没有人产生CPU)或者因未处理的异常而失败.幸运的是,Eventlet为这两个问题提供了两种解决方案:超时 with_timeout()允许限制等待时间(记住,如果它不产生,你不可能限制它)和GreenThread.link()来捕获所有异常.可能很诱人(对我而言)在"主"代码中重新引用异常,并link()允许这很容易,但考虑到睡眠和IO调用会产生异常 - 你屈服于Hub的地方.这可能会提供一些非常直观的追溯.
| 归档时间: |
|
| 查看次数: |
3912 次 |
| 最近记录: |