在Python中并发执行QThread或QRunnable对象

时间:2012-05-14 22:47:33

标签: python multithreading qt thread-safety pyqt

我有以下代码:

from PySide.QtCore import *
import time

class GUI(object):

    IDLIST = [i for i in xrange(20)]
    UNUSEDIDS = [i for i in xrange(20)]

    def __init__(self):
        print "GUI CLASS INITIALIZED!"

        worker = Worker()
        worker2 = Worker2()

        threadpool = QThreadPool()
        threadpool.setMaxThreadCount(10)

        for i in xrange(5):
            #Alternate between the two
            #threadpool.start(worker)
            #worker2.start()


    @classmethod
    def delegator(self):
        """Irrelevant to the question, I need this method for something else"""
        USEDIDS = []

        toUse = self.UNUSEDIDS[0]
        USEDIDS.append(toUse)
        self.UNUSEDIDS.pop(0)

        return toUse


class Worker(QRunnable):

    def __init__(self, parent=None):
        super(Worker, self).__init__(parent)

    def run(self):
        #idInUse = getattr(GUI, "delegator")
        idInUse = GUI.delegator()
        print "Hello world from QRunnable", idInUse
        #time.sleep(5)

class Worker2(QThread):

    def __init__(self, parent=None):
        super(Worker2, self).__init__(parent)

    def run(self):
        idInUse = GUI.delegator()
        print "Hello world from QThread", idInUse    


s = time.time()
GUI()
print "Done in %s" % ((time.time()-s) * 1000)

我认为从代码中可以看出期望的效果。我希望显示“来自QThread / QRunnable的Hello world”。由于我正在编写一个多线程应用程序,在我的GUI __init__部分中,我有一个启动并发线程的循环。

问题是,使用QRunnable它可以正常工作。我指定的所有5个线程同时执行。但是,使用QThread,情况并非如此。相反,我收到以下错误:

  

QThread:在线程仍在运行时被销毁

它根本没有执行。

通常我不介意使用QRunnable,但是,它不是从QObject派生的(因此我不能直接发出信号,虽然我可以在其中构建QObject())并且它也没有我迫切需要的.stop()方法。谷歌搜索透露,没有办法阻止QRunnable执行?另一方面,QThread有我需要的这两种方法。

所以我想我的问题是如何同时运行多个相同的QThread,或者如何终止执行QRunnable?

(另请注意,python的内置线程模块是不可能的)

1 个答案:

答案 0 :(得分:0)

发生QThread: Destroyed while thread is still running - 异常是因为您永远不会等待线程完成,并且您没有对它们进行任何引用(无论是workerworker2还是{{1所以,当你的threadpool完成时,它就会被破坏。

如果你保留对这个对象的引用,那么应该可以工作:

__init__

并且在线程/池上调用def __init__(self): print "GUI CLASS INITIALIZED!" self.worker = Worker() self.worker2 = Worker2() self.threadpool = QThreadPool() self.threadpool.setMaxThreadCount(10) for i in xrange(5): #Alternate between the two self.threadpool.start(worker) # this is wrong, by the way! # you should create 5 workers, not call start 5 times... self.worker2.start() / wait方法甚至更好 对于waitForDone,这隐含地发生when it's (C++) destructor is called。如果情况并非如此,那么您的程序将无法与QThreadPool s一起使用。对于QRunnable nothing like this happens,它甚至提到它可能会导致崩溃。因此最好明确等待线程完成......

另外,我希望你已经知道this