首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >信号需要由QMutex保护吗?

信号需要由QMutex保护吗?
EN

Stack Overflow用户
提问于 2020-05-22 14:14:24
回答 1查看 211关注 0票数 0

我正在使用PyQt5和2 QThreads开发一个GUI,它将使用各自的信号,再加上一个用于将错误代码发送回GUI的共享信号。我知道QThreads是用来与pyqtSignals一起使用的,但是它们的行为是否包含了除您之外的两个不同线程发出共享信号的信号呢?另外,在共享信号上使用Qmutex会确保线程同时访问它吗?还是在处理信号时它是无用的?

我编写了这个运行正常的示例代码,但我不确定如何处理这些信号:

代码语言:javascript
复制
from PyQt5.QtCore import QObject, pyqtSignal, QThread, QCoreApplication
import time
import sys


class Class2(QThread):
    def __init__(self, signal):
        super().__init__()
        self.signal2 = signal

    def run(self):
        self.signal2.emit("Class 2 signal emitted")


class Class1(QThread):
    def __init__(self, signal):
        super().__init__()
        self.signal1 = signal

    def run(self):
        self.signal1.emit("Class 1 signal emitted")


class Action(QObject):
    shared_signal = pyqtSignal(str)

    def __init__(self):
        super().__init__()
        class1 = Class1(self.shared_signal)
        class2 = Class2(self.shared_signal)
        self.shared_signal.connect(self.action)
        class1.start()
        class2.start()
        time.sleep(1)

    def action(self, buffer):
        print(buffer)


app = QCoreApplication([])
Action = Action()
sys.exit(app.exec_())

谢谢你的帮助!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-22 16:09:43

信号本身是线程安全的,因为它们的主要任务是对信息进行排队,并为此使用互斥对象。

代码语言:javascript
复制
                ┌----------------------┐
                |                      |
                |         QUEUE        |
                |                      |
                └----------------------┘
                  ▲ ▲ ... ▲   | |     |
                  | |     |   ▼ ▼ ... ▼
                   SIGNALS      SLOTS

可能不是线程安全的是连接,因为它取决于连接的类型。我建议您阅读医生们以了解哪种连接是不安全的(例如,在存在于不同线程上的QObjects之间使用Qt::DirectConnection )。

在您的情况下,连接是安全的,另一方面,我认为time.sleep是不必要的,但这会导致对象在调用信号之前被销毁,因此一个可能的解决方案是:

代码语言:javascript
复制
import sys


from PyQt5.QtCore import pyqtSignal, pyqtSlot, QCoreApplication, QObject, QThread


class Class2(QThread):
    def __init__(self, signal, parent=None):
        super().__init__(parent)
        self.signal2 = signal

    def run(self):
        self.signal2.emit("Class 2 signal emitted")


class Class1(QThread):
    def __init__(self, signal, parent=None):
        super().__init__(parent)
        self.signal1 = signal

    def run(self):
        self.signal1.emit("Class 1 signal emitted")


class Action(QObject):
    shared_signal = pyqtSignal(str)

    def __init__(self):
        super().__init__()
        class1 = Class1(self.shared_signal, self)
        class1.finished.connect(class1.deleteLater)

        class2 = Class2(self.shared_signal, self)
        class2.finished.connect(class2.deleteLater)

        self.shared_signal.connect(self.action)
        class1.start()
        class2.start()

    @pyqtSlot(str)
    def action(self, buffer):
        print(buffer)


def main():

    app = QCoreApplication([])
    action = Action()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61957001

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档