如何检查线程中是否调用了析构函数

How to check destructor has been called in thread?

本文关键字:是否 调用 析构函数 线程 何检查 检查      更新时间:2023-10-16

我使用boost来启动一个线程,线程函数是我的类的成员函数,就像这样:

class MyClass {
public:
    void ThreadFunc();
    void StartThread() {
        worker_thread_ = boost::shared_ptr<boost::thread>(
        new boost::thread(boost::bind(&MyClass::ThreadFunc, this)));
    }
};

我将访问ThreadFunc中的一些成员变量:

while (!stop) {    
    Sleep(1000);  // here will be some block operations
    auto it = this->list.begin();
    if (it != this->list.end())
        ...
}

我不能永远等待线程返回,所以我设置了timeout:

stop = true;
worker_thread_->interrupt();
worker_thread_->timed_join(boost::posix_time::milliseconds(timeout_ms));

超时后,我将删除这个MyClass指针。这里有一个问题,ThreadFunc没有返回,它将有机会访问this及其成员变量。在我的例子中,迭代器是无效的,it != this->list.end()为真,所以如果使用无效的迭代器,我的程序将崩溃。

我的问题是如何避免它?或者如何检查this是否有效或成员变量是否有效?或者我可以设置一些标志来告诉ThreadFunc析构函数已经被调用了吗?

有很多可能的解决方案。一种方法是对类使用shared_ptr,并让线程对类持有自己的shared_ptr。这样,只有当两个线程都使用完该对象时,该对象才会自动销毁。

如何创建stopProcessing标志(使其原子化)作为MyClass的成员,并在ThreadFunc方法检查在每个周期,如果这个标志被设置?

[编辑:使答案更清晰]有两个正交问题:

  1. 停止处理(我失去了耐心,请立即停止)。这可以通过在MyClass中设置一个标志来安排,并使ThreadFunc尽可能频繁地检查它

  2. 资源回收。最好使用RAII——一个例子是使用shared_ptr

最好将它们作为独立的关注点。

将它们组合在一个操作中是可能的,但有风险。
。如果使用shared_ptr,一旦连接线程决定"我受够了",它就会离开保留shared_ptr"副本"的块,因此shared_ptr::use_count得到递减。线程函数可能会注意到这一点,并决定将其解释为"调用者受够了",并缩短处理时间。
然而,这意味着,在未来的版本中,没有其他人(除了两个线程)可以获得shared_ptr,否则"减少use_count意味着中止"的"契约"被打破。

(一个use_count==1条件可能仍然可用-解释"只有我,处理线程,似乎对结果感兴趣;没有消费者,最好放弃这项工作")。