Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 无法将当前flask请求上下文复制到多个gevent线程_Python_Flask_Gevent - Fatal编程技术网

Python 无法将当前flask请求上下文复制到多个gevent线程

Python 无法将当前flask请求上下文复制到多个gevent线程,python,flask,gevent,Python,Flask,Gevent,我正在尝试将Flask的当前请求上下文复制到gevent线程中,这样我就可以使用这些THRED中的原始请求上下文进行日志记录 我参考了下面的链接。 当我只生成1个gevent线程时,使用decorator@copy\u current\u request\u上下文可以很好地工作。但如果生成多个线程,则会引发以下异常。似乎每个线程都从另一个线程推送的堆栈中弹出一个错误的上下文 AssertionError: Popped wrong app context. (<flask.ctx.Ap

我正在尝试将Flask的当前请求上下文复制到gevent线程中,这样我就可以使用这些THRED中的原始请求上下文进行日志记录

我参考了下面的链接。

当我只生成1个gevent线程时,使用decorator
@copy\u current\u request\u上下文可以很好地工作。但如果生成多个线程,则会引发以下异常。似乎每个线程都从另一个线程推送的堆栈中弹出一个错误的上下文

AssertionError: Popped wrong app context.  (<flask.ctx.AppContext object at 0x7f57983b7ba8> instead of <flask.ctx.AppContext object at 0x7f57983be9b0>
有什么办法解决这个问题吗?

您可以这样做:

top = flask.globals._request_ctx_stack.top
# copy the request context
reqctx = top.copy()
def do_some_work(item):
    # Here the context stack is not the same as above, since do_some_work
    # is called in a greenlet, the stack returned is empty. 
    flask.globals._request_ctx_stack.push(reqctx)

    # ----------- do your work here -----------------


    flask.globals._request_ctx_stack.pop() # very important to do this, or your memory will explose 

threads = [gevent.spawn(do_some_work, item) for item in items] 
更好的版本是将“推送”和“弹出”操作放入上下文管理器中,我让您这样做

top = flask.globals._request_ctx_stack.top
# copy the request context
reqctx = top.copy()
def do_some_work(item):
    # Here the context stack is not the same as above, since do_some_work
    # is called in a greenlet, the stack returned is empty. 
    flask.globals._request_ctx_stack.push(reqctx)

    # ----------- do your work here -----------------


    flask.globals._request_ctx_stack.pop() # very important to do this, or your memory will explose 

threads = [gevent.spawn(do_some_work, item) for item in items]