6

次のコードは、終了するのに1秒かかるプロセスを開始し、その後、そのプロセスが終了するのを待ってから終了します。何らかの理由で、p->waitForFinished()プロセスが終了したにもかかわらず、次のコードがハングします。

#include <QtCore/QProcess>    

class A
{
  public:
    A():
        p(0)
    {
    }

    ~A()
    {
        p->waitForFinished();
        delete p;
    }

    void start()
    {
        p = new QProcess(0);
        p->start("sleep 1");
    }

    QProcess *p;
};

int main(void)
{
  static A a;
  a.start();

  return 0;
}

ただし、a静的に宣言されていない場合は、次のようになります。

A a;

waitForFinished()呼び出しは成功します。これはQtのバグですか、それとも予想される動作ですか?私の疑惑は、アプリケーションが正常に終了したかどうかを検出するために必要なある種のロジックが、のデストラクタAが呼び出されるとすでに破棄されていることです。

4

1 に答える 1

10

QProcess2つの異なる方法で同時に作成されたスレッドをクリーンアップしようとしたため、これはプログラムのバグです。

から戻ることでスレッドを切り離しましたmain(これにより、プロセス内のすべてのスレッドが終了し、参加可能な場合は切り離されます)。

そして、をQProcess介してスレッドを結合することにより、スレッドをクリーンアップしましたwaitForFinished

スレッドを切り離したり、結合したりすることはできますが、間接的にでも両方を行うことはできません。どうやら、デタッチが勝ち、結合がハングします。

QProcessこれは、スレッドライブラリに組み込まれているものではなく、独自の終了信号を使用していることが原因である可能性があります。したがって、return frommainは、スレッドがその終了シグナルを送信する前にスレッドを終了し、送信waitForFinishedされないシグナルを待機するように関数を残します。

原則として、スレッドはコンストラクターで作成したり、デストラクタでクリーンアップしたりしないでください。これは主に、これらの操作のタイミングが可能なよりも明確な制御を必要とするためです。また、開始前に作成したり、返品main後にクリーンアップしたりしmainないでください。これらのことが発生するコンテキストを制御する必要があるためです。

于 2013-01-03T20:54:50.477 に答える