1

私は次のコードを持っています:

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のHelloworld」を表示したいのですが。マルチスレッドアプリケーションを作成しているので、GUI__init__部分に、並行スレッドを開始するループがあります。

重要なのは、QRunnableを使用すると問題なく動作するということです。指定した5つのスレッドすべてが同時に実行されます。ただし、QThreadの場合は、そうではありません。代わりに、次のエラーが発生します。

QThread:スレッドの実行中に破棄されました

そして、それはまったく実行されません。

通常、QRunnableを使用してもかまいませんが、QObjectから派生したものではなく(そのため、内部で構築できますが、信号を直接送信することはできません)、また、私がひどく必要とQObject()するメソッドもありません。.stop()グーグルは、QRunnableの実行を停止する方法がないことを明らかにしましたか?一方、QThreadには、私が必要とするこれらのメソッドの両方があります。

ですから、私の質問は、複数の同じQThreadを同時に実行する方法、またはQRunnableの実行を終了する方法のいずれかだと思います。

(Pythonの組み込みスレッドモジュールは問題外であることにも注意してください)

4

1 に答える 1

0

-exception が発生するのQThread: Destroyed while thread is still runningは、スレッドが終了するのを決して待たず、スレッドへの参照を保持しないためです ( workerworker2または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/メソッドを呼び出すと、さらに優れています。 これは、(C++) デストラクタが呼び出されたときに暗黙的に発生します。そうでない場合、プログラムはそもそも eiter で動作しませんでした。このようなことは起こらず、おそらくクラッシュする可能性があるとさえ言われています。したがって、スレッドが終了するまで明示的に待つ方がよいでしょう...waitForDone
QThreadPoolQRunnableQThread

また、私はあなたがすでにこれを知っていることを願っています

于 2012-05-16T12:41:38.543 に答える