1

我有一个类,它有一个方法来启动一个线程,该线程以预定义的时间间隔Start执行虚拟。ThreadFunctionStop方法设置一个事件并等待线程终止(通过WaitForSingleObject线程句柄上的 a )。

在 的析构函数中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会先调用析构函数吗?因此,如果线程正在执行中的,则该方法将在被破坏后被调用。当调用已破坏的实例时,这可能会导致访问冲突。AMyThreadfor-loopThreadFunctionStopaThreadFunctionTestFunction

一种解决方案是向class A调用该Stop方法的析构函数添加一个析构函数,如下所示:

class A : MyThread
{
    ~A()
   {
       Stop();
   }
}

但是因为我有一个更复杂的类层次结构,它涉及多个继承的类,这意味着我必须Stop在每个析构函数中调用该方法,这将导致 Stop 方法被调用很多次,而只有一个需要删除的实例.

有没有其他方法可以解决这个问题?

4

2 回答 2

1

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;
}

结果是:A B做某事~B~A

而当它不使用virtual时,结果是:A B做某事~A

于 2012-08-09T09:41:00.960 回答
1

正如 Rolle 和 R. Martinho Fernandes 所建议的,我需要将这两个问题分开。

class MyThread不应启动或停止自身,因为它的责任应仅限于它执行的代码,而不是线程的生命周期。

所以解决方案是从另一个负责线程生命周期的类(启动线程的同一类)中停止线程。

于 2012-08-17T14:38:44.263 回答