在我的基于gevent的程序中,我有一个某个地方的线程,它在一个循环中很糟糕,如:
while True:
gevent.sleep(0)
我怎样才能弄清楚这是哪个线程?是否可以列出(并获取堆栈跟踪)正在运行的线程?
答案 0 :(得分:1)
我在我的代码中使用它来跟踪可能阻塞的greenlet。发生这种情况时会引发NodeTaskTimeout。只需将作业包装在Timeout中,或者为它们提供TimeOut对象。
with Timeout(90, False):
task_jobs.join()
if task_jobs:
print 'task jobs killed', task_jobs
task_jobs.kill()
if settings.DEBUG:
raise NodeTaskTimeout
如果它挂起/阻止/需要很长时间,则打印出该任务。 尤其令人讨厌的是那些相互依赖并造成僵局的工作 job1 / thread - > job2 / thread2 - > job3 / thread3和job / thread3只在job1完成后才会完成,因为job2没有完成而job2没有完成,因为job3没有完成而没有完成job2你得到了想法;)
http://www.rfk.id.au/blog/entry/detect-gevent-blocking-with-greenlet-settrace/
但是您还需要将您怀疑的代码放在with块中“旋转”。
答案 1 :(得分:0)
有一个官方的API用于检查该块,它将查明导致该块的确切行,请参见以下代码示例:
# gevent 1.3.7
# greenlet 0.4.15
# zope.event 4.4
import gevent
from gevent import config, get_hub
from gevent.events import IEventLoopBlocked
import logging
from pprint import pformat
import time
import zope.event
# initial logging
logging.basicConfig(level=logging.INFO)
log = logging.getLogger(__name__)
# setup gevent config
# enable the monitor thread
config.monitor_thread = True
config.max_blocking_time = 4
# start the monitor thread
hub = get_hub()
monitor = hub.start_periodic_monitoring_thread()
# register the event to logging system
def g(event):
log.error('Greenlet: {}, exceed the max blocking time: {}'.format(event.greenlet, event.blocking_time))
log.error(pformat(event.info))
event = IEventLoopBlocked()
zope.event.subscribers.append(g)
# you can also create you own monitoring function
# def check(hub):
# print('< periodic check in monitoring thread >')
#
# monitor.add_monitoring_function(check, 1)
def gl1():
# use time.sleep to trigger block
log.info('block at gl1 for 2 seconds')
time.sleep(2)
log.info('leave gl1 now')
def gl2():
# use time.sleep to trigger block
log.info('block at gl2 for 6 seconds should be detected')
time.sleep(6)
log.info('leave gl2 now')
def gl3():
# gevent.sleep will not block
log.info('gl3 will not block since it use gevent.sleep')
gevent.sleep(8)
log.info('leave gl3 now')
gevent.joinall([
gevent.spawn(gl3),
gevent.spawn(gl1),
gevent.spawn(gl2),
])
希望对您有帮助!