如何安全地删除析构函数中的线程指针

How to safely delete a thread pointer in a destructor?

本文关键字:析构函数 线程 指针 删除 何安全 安全      更新时间:2023-10-16

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

样本代码:

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()。一旦它返回,您就可以安全地删除指针。

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

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

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

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

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