问题
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?
回答1:
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.
来源:https://stackoverflow.com/questions/16517796/bottle-gevent-and-threading-gevent-is-only-usable-from-a-single-thread