为什么 PyQt 在没有信息的情况下崩溃?(退出代码 0xC0000409) [英] Why does PyQt crashes without information? (exit code 0xC0000409)

查看:142
本文介绍了为什么 PyQt 在没有信息的情况下崩溃?(退出代码 0xC0000409)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 PyQt 开发软件,但我经常遇到没有调试信息的软件崩溃(只有退出代码 0xC0000409).我正在使用 QThread,我写了一个这样的系统:

I'm trying to develop a software with PyQt, but I often get stuck on software crashes without debug information (only the exit code 0xC0000409). I'm using QThread, and I wrote a system like this:

class serialThreadC(QThread):
    updateOutBox = QtCore.pyqtSignal(str)
    updateStatus = QtCore.pyqtSignal(int)

    def __init__(self):
        super(serialThreadC, self).__init__()
        self.ser = False
        self.state = 0
        self.serialEnabled = False

    def run(self):
        while True:
            if self.state == -3 or self.state == -2:
                if self.SerialEnabled:
                    self.updatePB(20)
            elif self.state == 0:
                if self.serialEnabled:
                    self.updatePB(20)

    def ConnDisconn(self):
        self.serialEnabled = not self.serialEnabled

    def updatePB(self, stat):
        self.state = stat
        self.updateStatus.emit(self.state)

serialThread = serialThreadC()
serialThread.start()

## sw is a QDialog already loaded
serialThread.updateOutBox.connect(sw.updateOutBox)
serialThread.updateStatus.connect(sw.updateStatus)

sw.PB_ConnDisconn.clicked.connect(serialThread.ConnDisconn)

当我在 run()ConnDisconn() 中读/写 serialEnabled 时发生崩溃.我知道 PyQt 不是线程安全的,并且错误处理变量会导致我的类型崩溃,但我无法理解我的代码有什么问题.我的想法(可能是错误的)是所有 serialThread 方法都在同一个线程上执行,如果它们连接到 gui(主线程).错了吗?以同样的方式,我从 serialThread 发出事件并将它们连接到 GUI,但这从来没有给我带来问题.

I have crashes when I read/write serialEnabled in run() or in ConnDisconn(). I know that PyQt is not thread-safe and that a wrong handling of variables gives crashes of my type, but I can't understand what is wrong with my code. My idea (maybe wrong) is that all serialThread methods are executed on the same thread, also if they are connected to a gui (main thread). Is that wrong? In the same way, I emit events from serialThread and I connected them to the GUI, but that never gave me problems.

你能看到我犯的错误吗?如果在没有其他信息的情况下发生崩溃,有没有办法调试代码?(我使用的是 PyCharm 2017.1.3).

Can you see the mistake I made? Is there a way to debug the code if there is a crash without other infos? (I use PyCharm 2017.1.3).

推荐答案

PyQt 是线程安全的,与 Qt 是线程安全的程度相同.Qt 文档会告诉您他们的 API 的哪些部分可以保证如此,以及在什么情况下.

PyQt is thread-safe to the same extent that Qt is thread-safe. The Qt docs will tell you which parts of their API are guaranteed to be so, and under what circumstances.

跨线程信号是线程安全的,因此在您的示例中调用 updatePB 方法是可以的.您的 ConnDisconn 方法不是线程安全的,但这与 PyQt 或 Qt 无关 - 这只是您编写它的方式的结果.serialEnabled 属性可以被两个线程同时读/写,所以行为是严格未定义的.一种线程安全的编写方式是使用 mutex,就像这样:

Cross-thread signals are thread-safe, so calling the updatePB method in your example is okay. Your ConnDisconn method is not thread-safe, but that has got nothing to do with PyQt or Qt - it's just a consequence of how you wrote it. The serialEnabled attribute could be read/written by two threads simultaneously, so the behaviour is strictly undefined. A thread-safe way of writing this would be to use a mutex, like so:

class serialThreadC(QThread):
    updateOutBox = QtCore.pyqtSignal(str)
    updateStatus = QtCore.pyqtSignal(int)

    def __init__(self):
        super(serialThreadC, self).__init__()
        self.ser = False
        self.state = 0
        self._mutex = QMutex()
        self.serialEnabled = False   

    def ConnDisconn(self):
        self._mutex.lock()
        self.serialEnabled = not self.serialEnabled
        self._mutex.unlock()

    def run(self):
        while True:
            if self.state == -3 or self.state == -2:
                self._mutex.lock()
                if self.serialEnabled:
                    self.updatePB(20)
                self._mutex.unlock()
            elif self.state == 0:
                self._mutex.lock()
                if self.serialEnabled:
                    self.updatePB(20)
                self._mutex.unlock()

(注意:如果您使用任何类型的 IDE 或调试器,并且遇到意外错误或崩溃,则诊断问题的第一步应该始终是在标准控制台中测试代码.通常,IDE 或调试器本身可能是问题的原因,或者可能掩盖来自 Python 或底层库(例如 Qt)的错误消息).

(NB: if you're using any kind of IDE or debugger, and you are getting unexpected errors or crashes, your first step in diagnosing the problem should always be to test the code in a standard console. Quite often, the IDE or debugger itself can be the cause of the problem, or may mask error messages comming either from Python or from underlying libraries, such as Qt).

这篇关于为什么 PyQt 在没有信息的情况下崩溃?(退出代码 0xC0000409)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆