python多线程死锁检测代码,python多线程代码,在多线程程序中经常会出现


在多线程程序中经常会出现资源争用死锁的问题,下面的代码可以帮助你找到死锁的原因:

"""Stack tracer for multi-threaded applications.Usage:import stacktracerstacktracer.start_trace("trace.html",interval=5,auto=True) # Set auto flag to always update file!....stacktracer.stop_trace()"""import sysimport tracebackfrom pygments import highlightfrom pygments.lexers import PythonLexerfrom pygments.formatters import HtmlFormatter# Taken from http://bzimmer.ziclix.com/2008/12/17/python-thread-dumps/# translated by http://byrx.net/ def stacktraces():    code = []    for threadId, stack in sys._current_frames().items():        code.append("\n# ThreadID: %s" % threadId)        for filename, lineno, name, line in traceback.extract_stack(stack):            code.append('File: "%s", line %d, in %s' % (filename, lineno, name))            if line:                code.append("  %s" % (line.strip()))    return highlight("\n".join(code), PythonLexer(), HtmlFormatter(      full=False,      # style="native",      noclasses=True,    ))# This part was made by nagylzsimport osimport timeimport threadingclass TraceDumper(threading.Thread):    """Dump stack traces into a given file periodically."""    def __init__(self,fpath,interval,auto):        """        @param fpath: File path to output HTML (stack trace file)        @param auto: Set flag (True) to update trace continuously.            Clear flag (False) to update only if file not exists.            (Then delete the file to force update.)        @param interval: In seconds: how often to update the trace file.        """        assert(interval>0.1)        self.auto = auto        self.interval = interval        self.fpath = os.path.abspath(fpath)        self.stop_requested = threading.Event()        threading.Thread.__init__(self)    def run(self):        while not self.stop_requested.isSet():            time.sleep(self.interval)            if self.auto or not os.path.isfile(self.fpath):                self.stacktraces()    def stop(self):        self.stop_requested.set()        self.join()        try:            if os.path.isfile(self.fpath):                os.unlink(self.fpath)        except:            pass    def stacktraces(self):        fout = file(self.fpath,"wb+")        try:            fout.write(stacktraces())        finally:            fout.close()_tracer = Nonedef trace_start(fpath,interval=5,auto=True):    """Start tracing into the given file."""    global _tracer    if _tracer is None:        _tracer = TraceDumper(fpath,interval,auto)        _tracer.setDaemon(True)        _tracer.start()    else:        raise Exception("Already tracing to %s"%_tracer.fpath)def trace_stop():    """Stop tracing."""    global _tracer    if _tracer is None:        raise Exception("Not tracing, cannot stop.")    else:        _trace.stop()        _trace = None

我经常写一些多线程的程序,有时候就会遇到死锁的问题,上面的代码对检测死锁非常有用。用法:

import stacktracer stacktracer.trace_start("trace.html")

通过调用上面的代码会成成一个trace.html文件,文件里有所有线程的调用堆栈。默认情况下这个文件会5分钟更新一次,只需要观察这个文件的内容就能知道到底是什么导致了死锁。

评论关闭