简体   繁体   English

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

[英]How to safely delete a thread pointer in a destructor?

Say, I have a C++ class including a thread pointer as a member variable. 说,我有一个C ++类,包括一个线程指针作为成员变量。 The thread keeps running until the program exits. 线程一直运行,直到程序退出。 If I delete the pointer in the destructor, it seems that the thread has not yet finished at that moment? 如果我删除了析构函数中的指针,那么该时刻线程似乎尚未完成? What is the best practice to manage this or any tricks? 管理这个或任何技巧的最佳做法是什么?

Sample code: 示例代码:

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?
}

By default the destructor will call terminate() to kill the thread if it's still running, whether this is safe or not depends on what the thread is doing at the time. 默认情况下,析构函数将调用terminate()来杀死线程,如果它仍然在运行,这是否安全取决于线程当时正在做什么。 You can call join() before deleting it if you want to wait for the thread to finish, and use some sort of synchronization system (even just a global flag) that tells the thread to quit. 如果要等待线程完成,可以在删除之前调用join() ,并使用某种同步系统(甚至只是一个全局标志)来告诉线程退出。

It depends on what kind of behavior you're looking for. 这取决于你正在寻找什么样的行为。

If you want to delete the object, and have it stop its owned thread and then delete its thread object, then you should have a stop flag which your thread checks from time to time. 如果要删除该对象,并让它停止其拥有的线程然后删除其线程对象,那么您应该有一个停止标志,您的线程会不时检查。 In the destructor, you'd set the stop flag, and then call join() on your thread. 在析构函数中,您将设置stop标志,然后在您的线程上调用join() Once it returns, you can safely delete the pointer. 一旦它返回,您可以安全地删除指针。

If, on the other hand, you want to delete the object and have the thread go on its own until it finishes, then you need a more clever mechanism, like at the end of your thread function, posting to the main thread of your application a callback that calls join() on your thread and then delete s it. 另一方面,如果你想要删除对象并让线程自行完成直到完成,那么你需要一个更聪明的机制,比如在线程函数的末尾,发布到你的应用程序的主线程一个在你的线程上调用join()然后delete它的回调。 For that, of course, you'll need to have in your thread function a pointer to your thread object. 当然,为此,您需要在线程函数中包含指向线程对象的指针。

EDIT In the case of boost::thread , it simply detaches in its destructor, so for the second option you can safely delete it when you're done. 编辑boost::thread的情况下,它只是在析构函数中分离,因此对于第二个选项,您可以在完成后安全地删除它。 It's important to note, however, that this won't work with std::thread 's destructor, which will terminate your program in such a case. 但是,重要的是要注意,这不适用于std::thread的析构函数,它会在这种情况下终止你的程序。 But then you can also manually call detach() and then delete . 但是你也可以手动调用detach()然后delete So you really have to look at the API you're using. 所以你真的要看看你正在使用的API。

Don't delete it. 不要删除它。 Have the thread delete itself when done. 完成后让线程自行删除。

Your program is done when there's no more code to run. 当没有更多代码可以运行时,您的程序就完成了。 Are your threads still running code? 你的线程仍在运行代码吗? Then why do you think your program is done? 那为什么你认为你的程序已经完成了?

So, it's reasonable to assume your threads are i fact done. 所以,假设你的线程是我完成的,这是合理的。 That means you can call .join() on the thread, after which it is OK to call delete . 这意味着您可以在线程上调用.join() ,之后可以调用delete

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM