0
tbb::tbb_thread*                    m_tbbTimerThread;
m_tbbTimerThread = new tbb::tbb_thread(&sFirstTimerBlocked, this);

// 上面的线程被生成。

后来我想删除不同功能的线程。我正在做如下。

if(m_tbbTimerThread != NULL ) 
{
    delete m_tbbTimerThread;
}

m_tbbTimerThread = NULL;

这是正确的做法吗。

谢谢!

4

1 回答 1

2

取决于您对“正确”的概念。

一般来说,销毁仍然连接到正在运行的线程的线程对象是一个坏主意。C++11std::thread将通过调用来奖励您std::terminate尝试此操作。TBB 更加宽容(线程在破坏时简单地分离),但这并不能解决根本问题。

特别是,您可能会失去保证彻底关机的最后机会。如果你的进程退出了,你怎么能保证分离的线程不在向磁盘写东西的过程中呢?如果线程没有明确清理它们就死了,你怎么能保证它不会保留一些会泄漏的持久句柄?请注意,如果线程由于父进程死亡而被杀死,RAII 可能不会启动。一般来说,分离一个线程对于除了最琐碎的线程之外的所有线程都是非常有问题的。

因此,可以说一种“更正确”的关机方式是:

if(m_tbbTimerThread != NULL ) 
{
    if(m_tbbTimerThread->joinable()) {
        <notify the thread to shutdown>
        m_tbbTimerThread->join();
    }
    delete m_tbbTimerThread;
}

对于非阻塞线程,单个原子标志可能已经足以实现关闭通知。

与每条规则一样,也有一个例外:有时您可以将监视职责转移到另一个对象,在这种情况下,分离线程可能会很好。例如,C++11std::async调用会产生一个新线程并返回一个在线程完成后将变为就绪的未来。等待未来与加入线程的目的相同,因此无需async返回显式线程对象。

于 2013-07-25T10:38:28.073 回答