いくつかのコードを非同期的に実行するクラスがあり、非同期コードがそのクラスインスタンスを使用して呼び出しメンバ関数、読み取りデータメンバなどを行うとすると、明らかに、クラスインスタンスはバックグラウンドスレッドよりもアクセス時間が長くなければなりません安全であるために。デストラクタのバックグラウンドスレッドに参加することでこれを保証すれば十分ですか?たとえば:デストラクタに参加して非同期作業を待つのは安全ですか?
#include <iostream>
#include <thread>
class foo final
{
public:
foo() = default;
void bar() {
std::cout << "Hopefully there's nothing wrong with using " << this << "\n";
}
void bar_async() {
if (!m_thread.joinable()) {
m_thread = std::thread{&foo::bar, this};
}
}
~foo() {
if (m_thread.joinable()) {
std::cout << "Waiting for " << m_thread.get_id() << "\n";
m_thread.join();
}
}
private:
std::thread m_thread;
};
int main() {
foo f;
f.bar_async();
}
は具体的に、私はobject lifetime rules心配:
デストラクタ些細なことではないクラスのいずれかのタイプのオブジェクトの場合、デストラクタの実行が開始されると寿命が終了します。
...オブジェクトの有効期間が終了したと、オブジェクトが占有ストレージを再利用またはリリースされる前に、そのオブジェクトを識別glvalue式の以下の用途が未定義された後:...
- 非静的データメンバーへのアクセスまたは非静的メンバー関数への呼び出し。
しかし私には、上記の厳密な読書も~foo()
内部からthis->bar()
を呼び出すと、直接「明らかに」そうではありませんこれは、未定義であることを暗示します。
'final'は多くの問題を解決します。あなたが「最終的」でない場合は、非常に注意してください。 – Yakk
これは実用的か法律的な質問ですか? – curiousguy
@curiousguy Legalistic –