线程完成后执行一些操作

时间:2009-12-17 10:03:59

标签: c++ winapi multithreading notifications

问候,大家!

我有一个类(比如说,“Switcher”)执行一些非常长的操作并通知其监听器,该操作已完成。操作很长,我将实际切换隔离到单独的线程中:

class Switcher
{
public:
    // this is what other users call:
    void StartSwitching()
    {
        // another switch is initiated, I must terminate previous switching operation:
        if ( m_Thread != NULL )
        {
            if ( WaitForThread(m_Thread, 3000) != OK ) 
            {
                TerminateThread(m_Thread);
            }
        }
        // start new switching thread:
        m_Thread = StartNewThread( ThreadProc );
    }

    // this is a thread procedure:
    static void ThreadProc()
    {
        DoActualSwitching();
        NotifyListener();
    }

private:
    Thread m_Thread;
};

逻辑相当简单 - 如果用户在前一个切换完成之前启动新切换,我终止先前的切换(不关心“DoActualSwitching()”内部发生的事情)并启动新的切换。问题是,有时候,当终止线程时,我会松开“NotifyListener()”调用。

我想介绍一些改进,以确保每次调用NotifyListener(),即使线程被终止。有没有任何模式可以做到这一点?我只能想到另一个线程,它无限地等待切换器,如果切换器完成(正确或通过终止),它可以发出通知。但引入另一个线程似乎对我来说过于夸张。你能想到任何其他解决方案(p.s.平台是win32)吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

首先,你永远不应该致电TerminateThread。调用TerminateThread时无法知道哪个操作被终止,因此可能导致内存泄漏/资源泄漏/状态损坏。

要使您的线程可中断/取消,您将提供“取消”状态,该状态由线程本身检查。然后您的通知结束将始终有效。

答案 1 :(得分:1)

TerminateThread()在这里敲击线程,如果它在DoActualSwitching()里面,那就是它会死的地方,并且不会在该线程上调用NotifyListener()。这就是TerminateThread()所做的,并且没有办法使它的行为不同。

您正在寻找的是一种更优雅的方式来终止线程。如果没有关于您的应用程序的更多信息,很难建议最佳方法,但如果您可以编辑DoActualSwitching(),那么我将添加

if (WAIT_OBJECT_0 == WaitForSingleObject(m_ExitThreadEvent, 0))
    break;

进入循环,并调用SetEvent(m_ExitThreadEvent)而不是TerminateThread()。当然,您需要创建事件并向该类添加句柄。如果你的模型建议一次只有一个切换线程,我会在这里使用autoreset事件,否则需要更多的代码。

祝你好运!