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

C++ 如何检查已在线程中调用析构函数?,c++,multithreading,boost,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))); }

我使用boost启动一个线程,线程函数是我的类的成员函数,如下所示:

class MyClass {
public:
    void ThreadFunc();
    void StartThread() {
        worker_thread_ = boost::shared_ptr<boost::thread>(
        new boost::thread(boost::bind(&MyClass::ThreadFunc, this)));
    }
};
我不能永远等待线程返回,所以我设置了超时:

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


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

如果设置了该标志,您可以创建一个
stopProcessing
标志(使其原子化)作为
MyClass
的一个成员,并在
ThreadFunc
方法中在每个周期检查是否设置了该标志

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

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

  • 取消分配资源。最好使用RAII—一个例子是使用共享的ptr

  • 最好将它们作为单独的关注点

    将它们结合在一个单一的操作中可能是可行的,但有风险。
    例如,如果使用shared_ptr,那么一旦加入线程决定“我受够了”,它就会退出保持其shared_ptr“副本”的块,因此
    shared_ptr::use_count
    会递减。线程函数可能会注意到这一点,并决定将其解释为“调用者已经受够了”并缩短处理时间。
    但是,这意味着,在未来的版本中,除两个线程外,没有其他线程可以获取
    共享的\u ptr
    ,否则“递减
    使用\u count
    意味着中止”的“约定”被打破


    (a
    use\u count==1
    条件可能仍然可用-解释“只有我,处理线程,似乎对结果感兴趣;没有消费者,最好中止工作”)。

    创建一个
    停止处理
    标志(使其原子化)作为
    MyClass
    的成员,在
    ThreadFunc
    方法中,检查每个周期是否设置了此标志

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

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

  • 取消分配资源。最好使用RAII—一个例子是使用共享的ptr

  • 最好将它们作为单独的关注点

    将它们结合在一个单一的操作中可能是可行的,但有风险。
    例如,如果使用shared_ptr,那么一旦加入线程决定“我受够了”,它就会退出保持其shared_ptr“副本”的块,因此
    shared_ptr::use_count
    会递减。线程函数可能会注意到这一点,并决定将其解释为“调用者已经受够了”并缩短处理时间。
    但是,这意味着,在未来的版本中,除两个线程外,没有其他线程可以获取
    共享的\u ptr
    ,否则“递减
    使用\u count
    意味着中止”的“约定”被打破


    (a
    use\u count==1
    条件可能仍然可用-解释“只有我,处理线程,似乎对结果感兴趣;没有消费者,最好中止工作”)。

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

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

    如果该对象仍在使用,为什么要删除
    MyClass
    ?看起来是个糟糕的设计。如果您需要线程在没有
    MyClass
    的情况下仍然是半可操作的,那么它不应该是成员。你需要对你身下可能被偷走的东西进行同步。最好使用原子共享的
    MyClass
    指针。并使
    ThreadFunc
    成为一个将其作为参数的自由函数。@vu1p3n0x是的,我认为这是一个糟糕的设计,共享指针似乎很好。您可能需要同步访问线程之间共享的数据。@n.m.是的,我添加了锁以进行同步。如果
    MyClass
    仍在使用,为什么要删除它?看起来是个糟糕的设计。如果您需要线程在没有
    MyClass
    的情况下仍然是半可操作的,那么它不应该是成员。你需要对你身下可能被偷走的东西进行同步。最好使用原子共享的
    MyClass
    指针。并使
    ThreadFunc
    成为一个自由函数,将其作为参数。@vu1p3n0x是的,我认为这是一个糟糕的设计,共享指针似乎不错。您可能需要同步访问线程之间共享的数据。@n.m.是的,我添加了锁来同步。析构函数会破坏
    停止处理吗?@zzy-我的建议是将处理的中断与破坏解耦。为什么要使用“销毁对象”作为“停止处理,我等得太久”的信号?
    stopProcessing
    会被析构函数销毁吗?@zzy-我的建议是将处理的中断与销毁分离开来。为什么要用“摧毁一个物体”作为一个信号
    stop = true;
    worker_thread_->interrupt();
    worker_thread_->timed_join(boost::posix_time::milliseconds(timeout_ms));