翻訳|間違っていません(スレッド)
2343 ワード
翻訳:https://woboq.com/blog/qthrea...
原作者:Olivier Goffart
発表期間:2013年1月22日
この文章はQThreadの使用についてです.これは私の当時の同僚Bradの3年前のブログの投稿に対する答えです:“あなたは間違っています”.
Brad氏はブログ記事で、多くのユーザーがQThreadをサブクラス化し、このサブクラスにいくつかのスロットを追加し、構造関数で以下の操作を実行することでQThreadを乱用しているのを見たと説明した.
スレッドを自分のクラスに移動します.Bradが述べたように、これはエラーです.QThreadはスレッドを管理するインタフェースであるべきです.したがって、作成スレッドで使用する必要があります.
これにより、スレッド内でQThreadオブジェクト内のスロットを実行することができず、QThreadのサブクラスにスロットを持つことはよくありません.
ただし、BradはQThreadの任意のサブクラスを継続し、完全に奨励しない.彼はこれが正しいオブジェクト向け設計に違反していると主張した.これは私が同意しないところです.挿入コード
Brad就任後、同コミュニティの一部のメンバーはQThreadのサブクラス化に反対して討伐した.問題は、QThreadを継承できる完全に合法的な理由がたくさんあることだ.
Qt 5.0およびQt 4.8.4では、QThreadのドキュメントが変更されているため、サンプルコードにはサブクラスは含まれません.Qt 4.8 QThreadドキュメントの最初のコード例を表示します(更新されたドキュメントは修正されました).多くのテンプレート行があり、スレッド内でコードを実行するためにのみ使用されます.さらに漏れも存在します:QThreadは永遠に脱退して破壊されません.
IRCでユーザーに質問されました.この例に従って、スレッド内で簡単なコードを実行します.彼はスレッドを正しく破棄する方法を明らかにするのは難しい.これが私にこのブログのエントリを書くように促した理由です.
サブクラス化QThreadが許可されている場合は、次のようになります.
このコードは漏洩せず、より簡単で、不要なオブジェクトは作成されないため、オーバーヘッドが小さくなります.
Qtスレッドの例threadedfortuneserverは、このモードを使用してブロック操作を実行する例であり、workerオブジェクトを使用する等価な例よりもずっと簡単です.
QThreadのサブクラス化を再び阻止しないように、ドキュメントにパッチを送信しました.
スレッド内のイベントループを必要としない場合は、サブクラス化する必要があります. イベントループが必要であり、スレッド内の信号およびスロットを処理する必要がある場合、サブクラス化は必要ない場合がある.
QThreadのレベルは低いので、QtConcurrentなどのより高いレベルのAPIを使用したほうがいいです.
現在、QtConcurrentには独自の一連の問題があります.これは単一のスレッドプールにバインドされているため、ブロック操作を実行する場合は、良い解決策ではありません.実装には、パフォーマンスのオーバーヘッドをもたらす問題もあります.これらはすべて修復できます.Qt 5.1も改善されるかもしれません.
良い選択もC++11と標準ライブラリstd::threadとstd::asyncが現在1つのスレッドで実行されているコードの標準的な方法です.良いニュースは、他のすべてのQtスレッドの原語がネイティブスレッドと一緒に使用できることです.(必要に応じてQtはQThreadを自動的に作成します)
以前の文章「あなたがこのようにするのは間違っています...(翻訳文)」
原作者:Olivier Goffart
発表期間:2013年1月22日
この文章はQThreadの使用についてです.これは私の当時の同僚Bradの3年前のブログの投稿に対する答えです:“あなたは間違っています”.
Brad氏はブログ記事で、多くのユーザーがQThreadをサブクラス化し、このサブクラスにいくつかのスロットを追加し、構造関数で以下の操作を実行することでQThreadを乱用しているのを見たと説明した.
moveToThread(this);
スレッドを自分のクラスに移動します.Bradが述べたように、これはエラーです.QThreadはスレッドを管理するインタフェースであるべきです.したがって、作成スレッドで使用する必要があります.
これにより、スレッド内でQThreadオブジェクト内のスロットを実行することができず、QThreadのサブクラスにスロットを持つことはよくありません.
ただし、BradはQThreadの任意のサブクラスを継続し、完全に奨励しない.彼はこれが正しいオブジェクト向け設計に違反していると主張した.これは私が同意しないところです.挿入コード
run()
は、QThreadを拡張する有効なオブジェクト指向方法である.QThreadは、イベントループのみを開始するスレッドを表し、サブクラスは、その動作を実行するために拡張されたスレッドrun()
を表す.Brad就任後、同コミュニティの一部のメンバーはQThreadのサブクラス化に反対して討伐した.問題は、QThreadを継承できる完全に合法的な理由がたくさんあることだ.
Qt 5.0およびQt 4.8.4では、QThreadのドキュメントが変更されているため、サンプルコードにはサブクラスは含まれません.Qt 4.8 QThreadドキュメントの最初のコード例を表示します(更新されたドキュメントは修正されました).多くのテンプレート行があり、スレッド内でコードを実行するためにのみ使用されます.さらに漏れも存在します:QThreadは永遠に脱退して破壊されません.
IRCでユーザーに質問されました.この例に従って、スレッド内で簡単なコードを実行します.彼はスレッドを正しく破棄する方法を明らかにするのは難しい.これが私にこのブログのエントリを書くように促した理由です.
サブクラス化QThreadが許可されている場合は、次のようになります.
class WorkerThread : public QThread {
void run() {
// ...
}
};
void MyObject::startWorkInAThread()
{
WorkerThread *workerThread = new WorkerThread;
connect(workerThread, SIGNAL(finished()),
workerThread, SLOT(deleteLater()));
workerThread->start();
}
このコードは漏洩せず、より簡単で、不要なオブジェクトは作成されないため、オーバーヘッドが小さくなります.
Qtスレッドの例threadedfortuneserverは、このモードを使用してブロック操作を実行する例であり、workerオブジェクトを使用する等価な例よりもずっと簡単です.
QThreadのサブクラス化を再び阻止しないように、ドキュメントにパッチを送信しました.
経験法則.
いつサブクラス化しますか。いつサブクラス化しませんか。
QtConcurrentに変更しますか?
QThreadのレベルは低いので、QtConcurrentなどのより高いレベルのAPIを使用したほうがいいです.
現在、QtConcurrentには独自の一連の問題があります.これは単一のスレッドプールにバインドされているため、ブロック操作を実行する場合は、良い解決策ではありません.実装には、パフォーマンスのオーバーヘッドをもたらす問題もあります.これらはすべて修復できます.Qt 5.1も改善されるかもしれません.
良い選択もC++11と標準ライブラリstd::threadとstd::asyncが現在1つのスレッドで実行されているコードの標準的な方法です.良いニュースは、他のすべてのQtスレッドの原語がネイティブスレッドと一緒に使用できることです.(必要に応じてQtはQThreadを自動的に作成します)