如何检查析构函数已在线程中调用?

时间:2016-08-31 04:22:12

标签: c++ multithreading boost

我使用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())
        ...
}

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

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

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

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

2 个答案:

答案 0 :(得分:2)

有很多可能的解决方案。一种是对类使用shared_ptr,让线程将自己的shared_ptr保存到类中。这样,只有当两个线程完成后,对象才会自动被销毁。

答案 1 :(得分:0)

如果设置了stopProcessing并且在MyClass方法检查每个周期,如果设置了此标志,那么如何创建ThreadFunc标志(使其成为原子)?

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

  1. 停止处理(我失去了耐心,请立即停止)。这可以通过将标记设置为MyClass并使ThreadFunc尽可能经常地检查来安排

  2. 资源的重新分配。这是最好的使用RAII - 一个例子是使用shared_ptr

  3. 最好将它们作为单独的问题保留。

    在一次操作中组合它们可能是有可能的,但有风险。 例如
    如果使用shared_ptr,那么一旦加入的线程决定了#34;我就够了#34;它就会走出阻止它的#34;复制&#34; shared_ptr,因此shared_ptr::use_count递减。线程函数可能会注意到这一点并决定将其解释为&#34;调用者已经足够&#34;然而,这意味着,在未来的版本中,没有其他人(但两个线程)可能获得shared_ptr,否则&#34;合同&#34;减少use_count意味着中止&#39;坏了。

    (一个use_count==1条件仍然可以使用 - 解释&#34;只有我,处理线程,似乎对结果感兴趣;没有消费者,更好地中止工作&#34;)。