ここ数日間、私は QThread をサブクラス化せずに QThreads を使用するための新しい優先アプローチを試してきました。私が抱えている問題は、作成した一連のスレッドをシャットダウンしようとするときです。「スレッドの実行中に破棄されました」というメッセージが定期的に表示されます (デバッグ モードで実行している場合は、セグメンテーション フォールト ダイアログも表示されます)。私のコードは非常に単純で、インターネットで見つけた例に従ってみました。
私の基本的なセットアップは次のとおりです。別のスレッドで実行したい単純なクラスがあります。実際、このクラスの 5 つのインスタンスをそれぞれ別のスレッドで実行したいと考えています。各スレッドを開始するためのボタンと、各スレッドを停止するためのボタン (10 個のボタン) を備えた単純なダイアログがあります。「開始」ボタンの1つをクリックすると、テストクラスの新しいインスタンスが作成され、新しいQThreadが作成され、テストクラスオブジェクトをスレッドに取得するためにmovetothreadが呼び出されます...また、いくつかあるのでスレッドに移動する必要があるテスト クラス内の他のメンバーの場合、これらの他の項目で movetothread をさらに数回呼び出します。これらのアイテムの 1 つは QUdpSocket であることに注意してください。これは意味をなさないかもしれませんが、この方法でソケットを別のスレッドに移動できるようにしたかったのです...
スレッドの開始はすべて正常に機能しているようです。Linux の top コマンドを使用して、スレッドが作成されて実行されているかどうかを確認すると、期待どおりに表示されます。
スレッドの停止を開始すると、問題が発生します。上記のエラーがランダムに(またはランダムに見える)発生します。
別のスレッドで実行されるクラス:
// Declaration
class TestClass : public QObject
{
Q_OBJECT
public:
explicit TestClass(QObject *parent = 0);
QTimer m_workTimer;
QUdpSocket m_socket;
Q_SIGNALS:
void finished();
public Q_SLOTS:
void start();
void stop();
void doWork();
};
// Implementation
TestClass::TestClass(QObject *parent) :
QObject(parent)
{
}
void TestClass::start()
{
connect(&m_workTimer, SIGNAL(timeout()),this,SLOT(doWork()));
m_workTimer.start(50);
}
void TestClass::stop()
{
m_workTimer.stop();
emit finished();
}
void TestClass::doWork()
{
int j;
for(int i = 0; i<10000; i++)
{
j = i;
}
}
メイン アプリ内で、最初のスレッドを開始するために呼び出されるコード (他の各スレッドにも同様のコードが存在します)。
mp_thread1 = new QThread();
mp_testClass1 = new TestClass();
mp_testClass1->moveToThread(mp_thread1);
mp_testClass1->m_socket.moveToThread(mp_thread1);
mp_testClass1->m_workTimer.moveToThread(mp_thread1);
connect(mp_thread1, SIGNAL(started()), mp_testClass1, SLOT(start()));
connect(mp_testClass1, SIGNAL(finished()), mp_thread1, SLOT(quit()));
connect(mp_testClass1, SIGNAL(finished()), mp_testClass1, SLOT(deleteLater()));
connect(mp_testClass1, SIGNAL(finished()), mp_thread1, SLOT(deleteLater()));
connect(this,SIGNAL(stop1()),mp_testClass1,SLOT(stop()));
mp_thread1->start();
また、メイン アプリ内で、特定のスレッド (この場合はスレッド 1) の停止ボタンがクリックされると、このコードが呼び出されます。
emit stop1();
スレッドが問題なく停止して破棄されているように見えることがあります。それ以外の場合は、上記のエラーが発生します。
ガイダンスをいただければ幸いです。
ありがとう、
ブライアン