线程可能会自行分离,释放其资源。如果析构函数看到线程是可加入的,即仍在运行,让它加入。如果线程到达终点,则自分离。可能的竞争条件:is_joinable() 在析构函数中返回 true - 线程自行分离 - 析构函数加入并惨遭失败。所以使用互斥锁来保护线程的死亡:
struct ThreadContainer
{
std::mutex threadEndMutex;
std::thread theThread;
ThreadContainer()
: theThread([=]()
{
/* do stuff */
// if the mutex is locked, the destructor is just
// about to join, so we let him.
if (threadEndMutex.try_lock())
theThread.detach();
})
{}
~ThreadContainer()
{
// if the mutex is locked, the thread is just about
// to detach itself, so no need to join.
// if we got the mutex but the thread is not joinable,
// it has detached itself already.
if (threadEndMutex.try_lock() && theThread.is_joinable())
theThread.join();
}
};
PS:您甚至可能不需要调用 is_joinable,因为如果线程自行分离,它永远不会解锁互斥锁并且 try_lock 失败。
PPS:您可以使用 std::atomic_flag 代替互斥锁:
struct ThreadContainer
{
std::atmoic_flag threadEnded;
std::thread theThread;
ThreadContainer()
: threadEnded(ATOMIC_FLAG_INIT)
, theThread([=]()
{
/* do stuff */
if (!threadEnded.test_and_set())
theThread.detach();
})
{}
~ThreadContainer()
{
if (!threadEnded.test_and_set())
theThread.join();
}
};