1

QThread とマルチスレッドは初めてなので、正しく実行しているかどうかわかりません。プログラムは今のところクラッシュしていませんが、正しく実行できているかどうかを確認したいと思います。次のようなコードがあります (MyThreadClass は QThread から継承されます)。

std::vector<MyThreadClass* > workThreads;
for(int i=0;i<Solutions.size();i++)
{
    workThreads.push_back(new MyThreadClass(Solutions[i]));
}
for(int i=0;i<workThreads.size();i++)
{
    connect(workThreads[i], SIGNAL(finished()), this, SLOT(onFinished()));
    workThreads[i]->start();
}

bool finished = false;
while(!finished)
{
    if(m_finishedThread==workThreads.size())
        finished=true;

    this->msleep(10);
}

onFinished 関数は次のように指定されます。

void MyClass::onFinished()
{
    ++m_finishedThread;
}

したがって、while ループはすべてのスレッドが終了し、m_finishedThread 変数を更新するのを待っていることがわかります。これは安全な方法ですか?すべてのスレッドがジョブを終了し、onFinished() 関数に「接続」しようとすると、問題が発生しますか?

4

5 に答える 5

1

まず第一に、QThread直接サブクラス化すべきではありません。参照: https://www.qt.io/blog/2010/06/17/youre-doing-it-wrong

代わりに通常のクラス (QObjectまたは同様のサブクラス) を作成し、そこにコードを実装します。次にmoveToThread()、サブクラスをそのスレッドに移動するために使用します。

Qt::QueuedConnection渡されたパラメータがオブジェクトではなく、同期メカニズムなしでそれらのオブジェクトのメソッドを呼び出していない限り、を使用してオブジェクトのスロットにシグナルを接続しても安全です。

とにかく、やりたいことは、おそらく を使用して実装する方が簡単ですQtConcurrent

于 2013-09-23T07:36:49.997 に答える
1

while(!finished) ループを実行すると、メインスレッド (または while ループの実行中のスレッド) がハングするため、おそらく実行しないでしょう。代わりに、実行中のスレッドについて onFinished() をチェックインし、すべてが終了したらシグナルを送信します。

すべてのスレッドが終了するのを待つ必要がある場合でも、wait()-Condition があります。

変数を変更するには、Qt:QueuedConnection をシグナルとともに使用して、変数に直接アクセスできない場合に変数を変更できます。

複数のスレッドから変数に直接アクセスする場合は注意してください。異なるスレッドから同じ変数にアクセスする場合は、QMutex を使用することをお勧めします。

于 2013-09-23T09:38:37.900 に答える
0

一見、私はノーと言うでしょう。finished()実際、 connect の最後のパラメーター ( ConnectionType )を指定せずに、スレッド シグナルを接続しました。

ドキュメントからわかるように、このパラメーターを指定しない場合Qt::AutoConnectionは、デフォルトのパラメーターであり、シグナルが同じスレッドまたは別のスレッドのオブジェクトから送信された場合にプログラムが異なる動作をするように指定します。

この場合、Qt::QueuedConnectionがこれらの呼び出しに使用されます。つまり、シグナルがスロットへの呼び出しをトリガーすると、この呼び出しは受信スレッドのイベント ループのキューに入れられます。複数のスレッドが同時に終了した場合、呼び出しはonFinished()キューに入れられ、1 つずつ呼び出されます。

編集:さらに、スレッドに基づいて設計するための別のアプローチを検討することをお勧めします。これを読んで、ワーカー オブジェクトを作成してからスレッドに移動する必要があります。

于 2013-09-23T07:35:22.910 に答える