python - Python 守护进程关闭问题的调试技术

标签 python multithreading daemon

我正在使用 Python 线程(包括守护进程)做一些粗糙的事情。

我在某些测试中遇到间歇性错误:

Exception in thread myconsumerthread (most likely raised during interpreter shutdown):

请注意,没有提供堆栈跟踪/异常详细信息。

检查我自己的代码并没有帮助,但我对调试的下一步有点茫然。 我可以使用哪些调试技术来详细了解关闭期间哪些异常可能会导致运行时下降?

细则:

  • Windows、CPython、2.7.2 - 无法在 Ubuntu 上重现。
  • 该问题发生的概率约为 3% - 可以重现,只是不可靠。
  • myconsumerthread 中的代码有一个捕获所有异常的处理程序,它尝试将异常的名称写入 sys.stderr。 (sys 是否已经关闭?)
  • 怀疑问题与快速关闭守护线程有关;在它们完全初始化之前。 this 中的内容领域,但我几乎没有证据 - 当然不足以指出 Python 错误。
  • 哈,我发现了一种新症状,标志着我陷入疯狂的转折点!
    • 如果我在我的测试工具(不是实时代码)中导入时间,并且从不使用它,则频率会下降到大约 0.5 %。
    • 如果我在我的测试工具中导入海龟(我以我的生命发誓,我的代码中没有海龟图形;我选择它作为我可以快速找到的最不相关的库),异常就会开始被另一个线程捕获,并且它发生在大约三分之一的运行中。

最佳答案

我曾多次遇到同样的错误。我正在尝试查找/生成一个显示确切消息的示例。

在那之前,如果我没记错的话,这些都是我关注的领域。

  • 寻找在守护线程之外删除或关闭的端口、文件、队列等。
  • 仔细检查守护线程中的阻塞调用。 IE a Queue.get(block=True), pyserial.read() - 超时=None

进一步挖掘后,我发现弹出与队列的 see comments here 相关的相同类型的错误。 。

我觉得奇怪的是它不显示回溯。您可能会尝试注释掉所有的 except 并让 Python 将其发送到 std.error。希望那时你能够看到你身上正在死去的是什么。

更新
我知道我以前见过这个问题...下面您将找到一个生成该错误的示例(实际上有很多错误)。请注意,也没有其他回溯消息...为了在看到错误消息后完整起见,请取消注释 queue.get 行并注释掉 time.sleeps。错误应该消失。 再次重新运行后,错误不会出现...这与您在偶发故障率中看到的情况一致...您可能需要运行几次才能看到错误。

如果 get()read() 等阻塞 IO 不起作用,我通常使用 time.sleep(x) 来限制线程提供超时方法或者没有要使用的阻塞调用(例如用户界面刷新)。

话虽这么说,我相信在等待 time.sleep() 调用时关闭线程会出现问题。我相信这个调用每次都会让我困扰,但我不知道在 sleep 方法中到底是什么导致了它。据我所知,还有其他阻塞调用也显示出相同的行为。

import time
import Queue
from threading import Thread

SLAVE_CNT = 50
OWNER_CNT = 10
MASTER_CNT = 2

class ThreadHungry(object):
    def __init__(self):
        self.rx_queue = Queue.Queue()

    def start(self):
        print "Adding Masters..."
        for x in range(MASTER_CNT):
            self.owners = []
            print "Starting slave owners..."
            for y in range(OWNER_CNT):
                owner = Thread(target=self.__owner_action)
                owner.daemon = True
                owner.start()
                self.owners.append(owner)

    def __owner_action(self):
        self.slaves = []
        print "\tStarting slaves..."
        for x in range(SLAVE_CNT):
            slave = Thread(target=self.__slave_action)
            slave.daemon = True
            slave.start()
            self.slaves.append(slave)

        while(1):
            time.sleep(1)
            #self.rx_queue.get(block=True)

    def __slave_action(self):
        while(1):
            time.sleep(1)
            #self.rx_queue.get(block=True)


if __name__ == "__main__":
    c = ThreadHungry()
    c.start()

    # Stop the threads abruptly after 5 seconds
    time.sleep(5)

关于python - Python 守护进程关闭问题的调试技术,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16096223/

相关文章:

Python pandas 从数据帧生成列表

python - 如何并行运行具有不同参数的相同功能的N个线程? - Python

c++ - 守护进程子无法执行库

go - Docker 守护进程不启动或重新启动

c++ - 将 valgrind 附加到守护进程并为每个守护进程调用收集日志

python - 如何从 python-social-auth 获取后端实例

python - 强制使用 buildout 和 zc.recipe.egg :scripts 制作的脚本的无缓冲输出

python - matplotlib:我可以创建 AxesSubplot 对象,然后将它们添加到 Figure 实例吗?

android - mainActivity.runOnUiThread 更新表中的数据太慢

java - 响应时间随着 Java 中并发性的增加而增加