我使用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
析构函数是否已被调用?
答案 0 :(得分:2)
有很多可能的解决方案。一种是对类使用shared_ptr
,让线程将自己的shared_ptr
保存到类中。这样,只有当两个线程完成后,对象才会自动被销毁。
答案 1 :(得分:0)
如果设置了stopProcessing
并且在MyClass
方法检查每个周期,如果设置了此标志,那么如何创建ThreadFunc
标志(使其成为原子)?
[编辑:更清楚答案] 有两个正交问题:
停止处理(我失去了耐心,请立即停止)。这可以通过将标记设置为MyClass
并使ThreadFunc
尽可能经常地检查来安排
资源的重新分配。这是最好的使用RAII - 一个例子是使用shared_ptr
最好将它们作为单独的问题保留。
在一次操作中组合它们可能是有可能的,但有风险。
例如
如果使用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;)。