ワーカースレッドtWorker
があるとします。これはBoss
の構築時に初期化され、bRetired
がtrueになるまでwork()
を実行するように指示します。 _std::mutex
_、mtx
は、一部のデータ(vFiles
)をロックし、tWorker
が作業しているときにそれを所有します。
tWorker
がbRetired
になった後、true
を「自殺」する方法を教えてください。スレッドが実行を停止すると、mutex
はどのように破棄されますか?
_std::thread
_オブジェクトはいかなる方法でも中断できないことを読みました。スレッドに何もさせない(またはstd::this_thread::yield()
を呼び出す)と、スレッドを強制終了するのと同じ効果がありますか?
_class Boss {
private:
std::thread tWorker;
std::mutex mtx;
bool bRetired;
std::vector< std::string > vFiles;
void work() {
while ( bRetired == false ) {
// Do your job!
mtx.lock();
// ... Do something about vFiles ...
mtx.unlock();
}
// tWorker has retired, commit suicide
// ** How? **
// Does this suffice if I want to "kill" the thread?
std::this_thread::yield();
}
public:
Boss() {
bRetired = false;
tWorker = std::thread( &Boss::work, this );
// Have worker do its job independently
// **Bonus Question** : Should this be tWorker.join() or tWorker.detach()?
tWorker.detach();
}
retire() {
bRetired = true;
}
}
_
メモ
std::thread::yield()
の呼び出しは不要であり、呼び出しスレッドを強制終了しません。
実装のヒントを提供して、スレッドの実行を再スケジュールし、他のスレッドを実行できるようにします。
スレッドを終了するには、関数を終了するだけです。
2つのスレッドが同じメモリロケーションにアクセスでき、それらのスレッドの1つがそれを変更しているため、bRetired
の使用は正しくないことに注意してください。これは未定義の動作です。また、別のスレッドである関数retire()
で行われた変更は、run()
を実行するスレッドには表示されません。使用 _atomic<bool>
_ for原子性と可視性。
join()
がコンストラクター内で使用された場合、コンストラクターはスレッドが終了するまで戻りません。これは、retire()
を呼び出すことができないため、発生しません。オブジェクトは使用できません(コンストラクターが返されなかったため)。スレッドの終了と同期する必要がある場合は、detach()
関数ではjoin()
ではなくretire()
を使用してください。
_void retire() {
bRetired = true;
tWorker.join();
}
_
RAIIを使用してmutex
es( _std::lock_guard
_ など)を取得し、常に解放されるようにします。 mutex
は、スコープ外になると破棄されます。この場合は、その包含クラスが破棄されます。
BRetiredがtrueになった後、tWorkerを「自殺」する方法を教えてください。
制御フローにスレッド関数を終了させます。そのstd::this_thread::yield()
呼び出しは不要です。
スレッドが実行を停止すると、ミューテックスはどのように破棄されますか?
そのミューテックスはBoss
クラスのメンバーです。オブジェクトが破棄されるときに、Boss
のデストラクタで破棄されます。
Std :: threadオブジェクトを中断することはできません。
C++ APIは、任意のスレッドを終了する手段を提供しません。意図したとおり、スレッドに終了を指示し、終了するまで待機する方法が必要です。
スレッドに何もさせない(またはstd :: this_thread :: yield()を呼び出す)と、スレッドを強制終了するのと同じ効果がありますか?
番号。
ただし、bRetired
変数には競合状態があります。 std::atomic<bool>
または、そのmutexがロックされている場合にのみ、読み取りと変更を行う必要があります。