0

TCP 経由でデータを送信し、他のいくつかのスレッドからそのデータを取得するワーカー スレッドがあります。ある種のミューテックスを使用してデータを入力し、別のスレッドのメソッドを呼び出す必要があります。これにより、終了時にミューテックスのロックが解除され、呼び出し元のスレッドが独自のジョブを続行します。

次のように、Qtを使用してこれを最初に実装しました。

Data globalData;
QMutex mutex;

void requestSend() // several such functions in other threads
{
    mutex.lock(); // we want to change the data
    globalData=fillData();
    invokeMethod(workerClass,"work",Qt::QueuedConnection);
}

void work() // a slot in a class instanced in worker thread
{
    sendData(globalData);
    mutex.unlock(); // data is now available to be changed
}

これは合理的で機能しているように見えますが、QMutex のドキュメントでこれを見つけました。

void QMutex::unlock ()

ミューテックスのロックを解除します。ミューテックスをロックしたスレッドとは別のスレッドでミューテックスをロック解除しようとすると、エラーが発生します。ロックされていないミューテックスをロック解除すると、未定義の動作が発生します。

2 つの質問があります。

  1. 別のスレッドでロックを解除するためのそのような制限の理由は何ですか? (そして、ドキュメントに記載されているエラーが表示されないのはなぜですか?)

  2. QMutex の代わりに何を使用すれば、目的を達成できますか? QWaitCondition は適切な代替品でしょうか?

4

1 に答える 1

1

ミューテックスの目的は、一度に 1 つのスレッドだけがデータにアクセスできるようにすることです。したがって、あるスレッドでロックし、別のスレッドで同じミューテックスをロック解除することは、実際には意味がありません。

動作することがわかっている場合は、現時点ではおそらく幸運ですが、スレッドのタイミングが変わっても問題が発生しないというわけではありません。

何をしようとしているのか正確にはわかりませんが、globalData に書き込むことができるさまざまなスレッドがあり、それに書き込むとすぐに別のスレッドにデータを送信させてから、さらにデータを書き込む必要があるようです。グローバルデータに。

私が提案するのは、データの書き込みに関するミューテックスを作成し、シグナルを呼び出して、データを送信するスレッドにデータを送信することです。異なるスレッド上にあるため、データはいずれにせよコピーされます: -

void requestSend() // several such functions in other threads
{
    QMutexLocker locker(&mutex);
    globalData=fillData();
    emit SendData(globalData); // send signal to the thread which will send the data
}

例外が発生した場合でも、QMutexLocker を使用してロックが確実に解放されることに注意してください。

シグナルとスロットでのデータのコピーについてはあまり心配しないでください。Qt は非常に効率的であり、コンテナー オブジェクトを使用する場合、暗黙的な共有により、「書き込み時にコピー」のみを作成します。スレッド間でデータを渡すためにコピーを作成する必要がある場合でも、パフォーマンスの問題が見られない限り、特に気にする必要はありません。

最後に、ここで読むことができるように、暗黙的な共有とマルチスレッドはうまく連携できることに注意してください。

于 2013-11-07T13:23:56.020 に答える