首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何通过多线程任务发出emit信号

如何通过多线程任务发出emit信号
EN

Stack Overflow用户
提问于 2019-05-24 00:51:20
回答 1查看 1.7K关注 0票数 1

我试图通过多线程的方式发出一个信号。我创建了一个函数来执行计算(例如,func)。以及另一个函数,它接受该任务并在多个线程中运行它(例如,函数)。

当我使用父线程时,代码运行良好。但是,当我使用多个线程时,计算工作正常,但是没有发出信号。

我需要使用多线程,因为我正在编写的函数执行计算量很大的任务。

请在下面找到示例代码(在本例中我使用了简单的打印函数)

代码语言:javascript
复制
from PyQt5.QtCore import QObject, pyqtSignal,pyqtSlot
import time
from threading import Thread
import sys
import math
import concurrent.futures


class Plot2D(QObject):
    finish=pyqtSignal(float)

    def __init__(self):
        super(Plot2D,self).__init__()

    def Function(self):
        st = time.time()

        # Using parent thread
        # self.func()

        # Using multi-thread 1
        #t=Thread(target=self.func)
        #t.start()
        #t.join()

        # Using multi-thread 2
        with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
           f = executor.submit(self.func)
        en = time.time()
        print(en-st)

    def func(self):
        n=10
        v=(1*100/(n-1))

        for i in range(n):
            print('thread')
            self.finish.emit(v)

    def fprint(self):
        print('works')

obj=Plot2D()
obj.finish.connect(obj.fprint)
obj.Function()
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-24 01:46:46

您必须清楚以下概念:信号需要一个事件循环才能工作.

考虑到上述情况,解决办法是:

  • threading.Thread

您不应该使用join(),因为它阻塞了事件循环所在的主线程,而且由于上述原因,信号将无法工作。

代码语言:javascript
复制
from PyQt5 import QtCore
from threading import Thread


class Plot2D(QtCore.QObject):
    finished = QtCore.pyqtSignal(float)

    def Function(self):
        Thread(target=self.func).start()

    def func(self):
        n = 10
        v = 1 * 100 / (n - 1)

        for i in range(n):
            print("thread")
            self.finished.emit(v)

    @QtCore.pyqtSlot()
    def fprint(self):
        print("works")


if __name__ == "__main__":
    import sys

    app = QtCore.QCoreApplication(sys.argv)
    obj = Plot2D()
    obj.finished.connect(obj.fprint)
    obj.Function()
    sys.exit(app.exec_())

输出:

代码语言:javascript
复制
thread
thread
thread
works
thread
works
thread
works
thread
thread
works
thread
works
thread
thread
works
works
works
works
works
  • concurrent.futures

不要使用with,因为它将使执行器阻塞主线程(我们已经知道它会产生什么问题),它也调用executor.shutdown(wait = False)

代码语言:javascript
复制
from PyQt5 import QtCore
import concurrent.futures


class Plot2D(QtCore.QObject):
    finished = QtCore.pyqtSignal(float)

    def Function(self):
        executor = concurrent.futures.ThreadPoolExecutor(max_workers=3)
        f = executor.submit(self.func)
        executor.shutdown(wait=False)

    def func(self):
        n = 10
        v = 1 * 100 / (n - 1)

        for i in range(n):
            print("thread")
            self.finished.emit(v)

    @QtCore.pyqtSlot()
    def fprint(self):
        print("works")


if __name__ == "__main__":
    import sys

    app = QtCore.QCoreApplication(sys.argv)
    obj = Plot2D()
    obj.finished.connect(obj.fprint)
    obj.Function()
    sys.exit(app.exec_())

输出:

代码语言:javascript
复制
thread
thread
works
thread
works
thread
works
thread
works
thread
thread
works
thread
works
thread
works
thread
works
works
works
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56284583

复制
相关文章

相似问题

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