3

私はクラスの一部である関数を持っています。この関数には、関数の先頭にmutex.lockがあり、その戻りの直前にmutex.unlockがあります。現在、ミューテックスがロック状態でスタックしている状況に遭遇しました。この関数がそのミューテックスを使用してロックおよびロック解除する唯一の場所である場合、これを行うことができます。この関数は、メイン スレッドと 1 つまたは 2 つの他の QThreads から呼び出されます。

更新: 問題は、スレッドが関数呼び出し間でスリープしていないことが原因でした。たぶん、スリープの欠如がミューテックスを本当に速く再ロックしたのでしょうか? yieldCurrentThread(); を呼び出すこともできます。

4

4 に答える 4

5

関数で例外がスローされた場合、unlock()最後に実行されない可能性があります。このような場合に QMutex が確実にロック解除されるようにするには、QMutexLockerオブジェクトでロックを行うことができます。このオブジェクトは、例外後のスタックの巻き戻し中に発生した場合でも、破棄されると自動的にミューテックスのロックを解除します。

于 2010-01-22T23:19:41.833 に答える
1

Mac OS XI では、100% 正しいロジックでも QMutex がハングしていました。アトミック参照カウントを増減する QMutex のラッパー呼び出しを行いましたが、QMutex は、参照カウントが保持されているミューテックスがないことを示している場所でハングしていました。

これは Qt3 で 1 回発生し、最近の Qt (4.6.2 または 4.7.0、覚えていません) でもう一度発生しました。QMutex を OS プリミティブに直接アクセスするカスタム クラスに置き換えると、問題が解決しました。

ただし、私の場合、この問題は OS X でのみ発生したことに注意してください。Windows では、同じコードが完全に機能していました。

于 2011-02-23T18:01:23.793 に答える
0

ミューテックスは、同じ QThread からロックを解除した直後に再ロックしていたため、メイン スレッドがロックを戻す時間がありませんでした。sleep または yieldCurrentThread() を追加すると問題が修正されました

于 2010-01-27T02:58:32.867 に答える
0

私の推測では、この関数を呼び出す他のスレッドの 1 つがまだロックを保持しており、解放していないため、コードのそのセクションに入ろうとする次のスレッドは、ロックが解放されるまで待機する必要があります。

ロック/ロック解除コード内にブロッキング呼び出しはありますか?

Qt QMutexドキュメントから:

スレッドで lock() を呼び出すと、同じ場所で lock() を呼び出そうとする他のスレッドは、ロックを取得したスレッドが unlock() を呼び出すまでブロックされます。

于 2010-01-22T23:15:54.400 に答える