瓶子gevent和线程:gevent只能在单线程中使用[英] bottle gevent and threading: gevent is only usable from a single thread

本文是小编为大家收集整理的关于瓶子gevent和线程:gevent只能在单线程中使用的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我有一个使用线程的Python瓶应用程序.由于事实,我正在使用 monkey.patch ,线程正在阻止应用程序执行(从线程发射的对话框正在阻止瓶路线响应客户,直到被解雇.)

这里的一些研究表明,我应该在不尝试修补线程的情况下使用猴子补丁:

# Patch python's threads with greenlets
from gevent import monkey
monkey.patch_all(thread=False)

这不会阻止最小值示例我写了.

,但通过threading.setEvent()
等方法引起了这些错误 这是我遇到的错误:

C:\Users\IEUser\downloadloft-localserver>python mainserver.py
Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\Program Files\DownloadLoft\Python27\lib\threading.py", line 551, in _
_bootstrap_inner
self.run()
  File "C:\Program Files\DownloadLoft\Python27\lib\threading.py", line 753, in r
un
self.finished.wait(self.interval)
  File "C:\Program Files\DownloadLoft\Python27\lib\threading.py", line 403, in w
ait
self.__cond.wait(timeout)
  File "C:\Program Files\DownloadLoft\Python27\lib\threading.py", line 262, in w
ait
_sleep(delay)
  File "c:\users\admini~1\appdata\local\temp\easy_install-sch3hm\gevent-0.13.8-p
y2.7-win32.egg.tmp\gevent\hub.py", line 79, in sleep
switch_result = get_hub().switch()
  File "c:\users\admini~1\appdata\local\temp\easy_install-sch3hm\gevent-0.13.8-p
y2.7-win32.egg.tmp\gevent\hub.py", line 135, in get_hub
raise NotImplementedError('gevent is only usable from a single thread')
NotImplementedError: gevent is only usable from a single thread

Bottle v0.12-dev server starting up (using GeventSocketIOServer())...
Listening on http://localhost:8080/
Hit Ctrl-C to quit.

Exception in thread Thread-2:
Traceback (most recent call last):
  File "C:\Program Files\DownloadLoft\Python27\lib\threading.py", line 551, in _
_bootstrap_inner
self.run()
  File "C:\Program Files\DownloadLoft\Python27\lib\threading.py", line 753, in r
un
self.finished.wait(self.interval)
  File "C:\Program Files\DownloadLoft\Python27\lib\threading.py", line 403, in w
ait
self.__cond.wait(timeout)
  File "C:\Program Files\DownloadLoft\Python27\lib\threading.py", line 262, in w
ait
_sleep(delay)
  File "c:\users\admini~1\appdata\local\temp\easy_install-sch3hm\gevent-0.13.8-p
y2.7-win32.egg.tmp\gevent\hub.py", line 79, in sleep
switch_result = get_hub().switch()
  File "c:\users\admini~1\appdata\local\temp\easy_install-sch3hm\gevent-0.13.8-p
y2.7-win32.egg.tmp\gevent\hub.py", line 135, in get_hub
raise NotImplementedError('gevent is only usable from a single thread')
NotImplementedError: gevent is only usable from a single thread

这是gevent.monkeypatch的已知问题吗?有什么想法吗?

推荐答案

瓶子应用程序是螺纹的,因此您不能在瓶路线中调用的任何功能中使用gevent.

要帮助您,我需要推测您为什么使用线程.

如果要加速您的瓶子网站,Juste使用Cherrypy服务器:

pip install cherrypy 

(或者只是在当前的dir中丢弃樱桃dir,它是纯python服务器)

然后以这种方式运行您的瓶应用程序:

bottle.run(server='cherrypy')

如果是因为您想在不阻止响应的情况下进行非阻止呼叫(例如获取URL),则可以手动进行足够的操作:

  • 创建一个队列对象(这是一个特殊的队列,可以填充并在线程之间弹出).
  • 创建并运行无限的线程,而循环循环脱离队列并每次执行操作.
  • 当您需要非阻止呼叫时,将动作推到队列并携带一个.

本文地址:https://www.itbaoku.cn/post/1975357.html

问题描述

I have a python bottle application, which uses threads. due to the fact I'm using monkey.patch, the threads were blocking app execution (a dialog box fired from a thread was blocking bottle routes from responding to the client, until dismissed.)

A little research here showed I should use monkey patch without trying to patch Thread:

# Patch python's threads with greenlets
from gevent import monkey
monkey.patch_all(thread=False)

This does not block on a minimal example I wrote.

But raises these errors on intensive use with Threads, with methods like threading.setEvent()
This is the error I get:

C:\Users\IEUser\downloadloft-localserver>python mainserver.py
Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\Program Files\DownloadLoft\Python27\lib\threading.py", line 551, in _
_bootstrap_inner
self.run()
  File "C:\Program Files\DownloadLoft\Python27\lib\threading.py", line 753, in r
un
self.finished.wait(self.interval)
  File "C:\Program Files\DownloadLoft\Python27\lib\threading.py", line 403, in w
ait
self.__cond.wait(timeout)
  File "C:\Program Files\DownloadLoft\Python27\lib\threading.py", line 262, in w
ait
_sleep(delay)
  File "c:\users\admini~1\appdata\local\temp\easy_install-sch3hm\gevent-0.13.8-p
y2.7-win32.egg.tmp\gevent\hub.py", line 79, in sleep
switch_result = get_hub().switch()
  File "c:\users\admini~1\appdata\local\temp\easy_install-sch3hm\gevent-0.13.8-p
y2.7-win32.egg.tmp\gevent\hub.py", line 135, in get_hub
raise NotImplementedError('gevent is only usable from a single thread')
NotImplementedError: gevent is only usable from a single thread

Bottle v0.12-dev server starting up (using GeventSocketIOServer())...
Listening on http://localhost:8080/
Hit Ctrl-C to quit.

Exception in thread Thread-2:
Traceback (most recent call last):
  File "C:\Program Files\DownloadLoft\Python27\lib\threading.py", line 551, in _
_bootstrap_inner
self.run()
  File "C:\Program Files\DownloadLoft\Python27\lib\threading.py", line 753, in r
un
self.finished.wait(self.interval)
  File "C:\Program Files\DownloadLoft\Python27\lib\threading.py", line 403, in w
ait
self.__cond.wait(timeout)
  File "C:\Program Files\DownloadLoft\Python27\lib\threading.py", line 262, in w
ait
_sleep(delay)
  File "c:\users\admini~1\appdata\local\temp\easy_install-sch3hm\gevent-0.13.8-p
y2.7-win32.egg.tmp\gevent\hub.py", line 79, in sleep
switch_result = get_hub().switch()
  File "c:\users\admini~1\appdata\local\temp\easy_install-sch3hm\gevent-0.13.8-p
y2.7-win32.egg.tmp\gevent\hub.py", line 135, in get_hub
raise NotImplementedError('gevent is only usable from a single thread')
NotImplementedError: gevent is only usable from a single thread

Is this a known issue with gevent.monkeypatch? Any ideas?

推荐答案

Bottle applications are threaded, so you can't use gevent in any function called in bottle routes.

To help you, I need to speculate why you use threads.

If it's to accelerate your bottle website, juste use the cherrypy server :

pip install cherrypy 

(or just dump the cherrypy dir in your current dir, it's a pure Python server)

Then run your bottle app this way :

bottle.run(server='cherrypy')

If it's because you want to make non blocking calls (such as fetching URLs) without blocking the response, it's easy enought to do it manually :

  • Create a Queue object (it's a special queue that can be filled and popped between threads).
  • Create and run a thread with a infinite while loop unpoping the queue and doing actions every time.
  • When you need a non blocking call, push the action to the queue and carry one.