从析构函数停止线程的正确方法
Proper way to stop a thread from a destructor
我有一个类,它有一个Start
方法来启动一个以预定义的时间间隔执行虚拟ThreadFunction
的线程。Stop
方法设置一个事件并等待线程终止(通过线程句柄上的WaitForSingleObject
)。
在 MyThread
的析构函数中,我调用 Stop
方法。因此,每当我删除实例时,我都会确定线程在删除返回之前已停止。
class MyThread
{
void Start();
void Stop();
~MyThread() { Stop(); }
virtual VOID ThreadFunction() { }
};
接下来我有一个派生自MyThread
的类:
class A : MyThread
{
virtual VOID ThreadFunction()
{
for (int i = 0; i < 1000; i++)
TestFunction();
}
void TestFunction() { // Do something }
};
请考虑以下代码:
A a = new A();
a->Start();
delete a;
问题是delete a
会先调用A
的析构函数,然后再调用MyThread
的析构函数,对吗?因此,如果线程在ThreadFunction
中执行for-loop
,则Stop
方法将在a
被破坏后被调用。当ThreadFunction
调用TestFunction
已破坏的实例时,这可能会导致访问冲突。
解决方案是向调用 Stop
方法的class A
添加一个析构函数,如下所示:
class A : MyThread
{
~A()
{
Stop();
}
}
但是因为我有一个更复杂的类层次结构,它涉及多个继承的类,这意味着我必须在每个析构函数中调用 Stop
方法,这将导致只为一个需要删除的实例调用 Stop 方法很多次。
还有其他方法可以解决这个问题吗?
MyThread 中的析构函数应定义为"虚拟"。
class A{
public:
A(){cout<<"A"<<endl;}
virtual ~A(){cout<<"~A"<<endl;}
};
class B : public A{
public:
B(){cout<<"B"<<endl;}
~B(){cout<<"~B"<<endl;}
};
int main(){
A* b = new B();
cout<<"do something"<<endl;
delete b;
b = NULL;
return 0;
}
结果是:一个B做点什么~乙~一个
当它不使用虚拟时,结果是:一个B做点什么~一个
正如Rolle和R. Martinho Fernandes所建议的那样,我需要将这两个问题分开。
class MyThread
不应自行启动或停止,因为它的责任应仅限于它执行的代码,而不是线程的生存期。
因此,解决方案是从另一个类(启动线程的同一类)停止线程,该类负责线程的生存期。
相关文章:
- 方法重写线程C++中的概念
- 使用基类中的派生方法运行线程,而无需使用模板
- 将线程中的数据存储到全局容器的最佳方法?
- 处理影响跨不同线程共享对象的定时回调的最佳方法是什么?
- 如何将带有参数的方法传递给线程以执行?
- C++ POCO - 如何在不使用 run() 方法的情况下启动线程池上的线程?
- 在销毁期间从另一个线程调用对象上调用方法是否未定义行为?
- C++中的多线程:连接线程的正确方法
- 使用包含互斥锁的类的方法实例化 cpp11 线程
- 如何在JNI中从线程内部调用JAVA方法
- 如何从另一个线程调用颤振引擎方法
- 在另一个线程上发出 QObject 信号的正确方法?
- 在C++线程内实现多个计时器的最安全方法
- C++ std::线程调用方法,从对象原因到调用此类的析构函数
- 将指针传递到另一个线程的正确方法
- 在另一个 QThread 上运行成员方法时,无法将事件发送到其他线程拥有的对象
- 解决方法:QPixmap:在GUI线程之外使用pixmap是不安全的
- CPP:如何使用需要指针的方法创建线程
- 初始化线程的正确方法
- 从另一个线程更新QT小部件的一种详细方法