бутылка gevent и threading: gevent можно использовать только из одного потока

У меня есть приложение для бутылок с 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? Есть идеи?


person user1555863    schedule 13.05.2013    source источник


Ответы (1)


Приложения для бутылок являются многопоточными, поэтому вы не можете использовать gevent ни в одной функции, вызываемой в маршрутах для бутылок.

Чтобы помочь вам, мне нужно предположить, почему вы используете потоки.

Если это нужно для ускорения вашего веб-сайта с бутылкой, просто используйте сервер cherrypy:

pip install cherrypy 

(или просто скопируйте директорию cherrypy в вашу текущую директорию, это чистый сервер Python)

Затем запустите приложение для бутылок следующим образом:

bottle.run(server='cherrypy')

Если это связано с тем, что вы хотите совершать неблокирующие вызовы (например, получать URL-адреса) без блокировки ответа, достаточно просто сделать это вручную:

  • Создайте объект Queue (это специальная очередь, которую можно заполнять и выталкивать между потоками).
  • Создайте и запустите поток с бесконечным циклом while, открывающим очередь и выполняющим действия каждый раз.
  • Когда вам нужен неблокирующий вызов, поместите действие в очередь и перенесите его.
person e-satis    schedule 26.10.2013