如何安全地删除析构函数中的线程指针? ,我有一个C++类,其中包含一个线程指针作为成员变量。线程将一直运行,直到程序退出如果我删除析构函数中的指针,那么此时线程似乎还没有完成?管理此技巧或任何技巧的最佳实践是什么

如何安全地删除析构函数中的线程指针? ,我有一个C++类,其中包含一个线程指针作为成员变量。线程将一直运行,直到程序退出如果我删除析构函数中的指针,那么此时线程似乎还没有完成?管理此技巧或任何技巧的最佳实践是什么,c++,multithreading,C++,Multithreading,示例代码: class Car { public: Car(); ~Car(); private: boost::thread *m_runningThreadPtr; }; Car::Car() { m_runningThreadPtr = new boost::thread(); } Car::~Car() { delete m_runningThreadPtr; // The thread should be still running

示例代码:

class Car {
public:
    Car();
    ~Car();
private:
    boost::thread *m_runningThreadPtr;
};


Car::Car() {
    m_runningThreadPtr = new boost::thread();
}

Car::~Car() {
    delete m_runningThreadPtr;    // The thread should be still running now. 
                                  // Problematic if it was deleted here?
}

默认情况下,析构函数将调用
terminate()
,以在线程仍在运行时终止线程,这是否安全取决于线程当时正在执行的操作。如果要等待线程完成,可以在删除前调用
join()
,并使用某种同步系统(甚至只是一个全局标志)通知线程退出。

不要删除它。完成后,让线程删除自己。

当没有更多代码运行时,程序就完成了。你的线程还在运行代码吗?那你为什么认为你的计划完成了


所以,假设你的线程已经完成是合理的。这意味着您可以在线程上调用
.join()
,之后可以调用
delete

这取决于你想要什么样的行为

如果您想删除对象,并让它停止其拥有的线程,然后删除其线程对象,那么您应该有一个停止标志,线程会不时检查该标志。在析构函数中,设置停止标志,然后在线程上调用
join()
。一旦它返回,您就可以安全地删除指针

另一方面,如果您想删除对象并让线程自己运行直到完成,那么您需要一个更聪明的机制,比如在线程函数的末尾,向应用程序的主线程发送一个回调,该回调在线程上调用
join()
,然后
删除它。当然,为此,您需要在线程函数中有一个指向线程对象的指针

编辑 对于
boost::thread
,它只是在析构函数中分离,因此对于第二个选项,您可以在完成后安全地删除它。
但是,需要注意的是,这对
std::thread
的析构函数不起作用,在这种情况下,析构函数将终止您的程序。但是,您也可以手动调用
detach()
,然后
delete
。因此,您真的必须查看您正在使用的API。

尝试使用boost::shared\u ptr处理。为什么您首先要对线程使用
new
?这似乎很不必要。您应该优雅地退出该线程,然后加入以等待它结束,如下所示:Car::~Car(){m_runningThreadPtr->join();delete m_runningThreadPtr;}。请注意,这是
boost::thread
,而不是
std::thread
。它将调用
分离
,而不是
终止
。到目前为止,删除线程对象是“无害的”(尽管仍然不可取),因为分离的线程不会被终止。根据API的不同,这可能是危险的。例如,线程对象的析构函数可能会对自身调用
join()
,从而导致死锁。