none
结束一个Sleep的线程 RRS feed

  • 问题

  • 一个简单的界面上就2个按钮:开始和结束;开始按钮是开启线程,结束按钮是关闭线程。大概代码如下:

    BOOL g_flag=FALSE;
    
    UINT test(LPVOID pParam)
    {
    	while(true)
    	{
    		// 方案一
    		if(g_flag)
    			return 1;
    		// 方案一
               ……
    		::Sleep(10000);
    	}
    
    	return 1;
    }
    
    CWinThread *m_pThread=NULL; 
    
    void Ctest线程死循环Dlg::OnBnClickedStart()
    {
    	// TODO: 在此添加控件通知处理程序代码
    	if(!m_pThread)
           m_pThread=AfxBeginThread(test,this);
         else
           ::AfxMessageBox(_T("正在运行中,请稍等!"));
    
    }
    
    void Ctest线程死循环Dlg::OnBnClickedStop()
    {
    	// TODO: 在此添加控件通知处理程序代码
    
    	// 方案一
    	if(m_pThread)
    	{
    		g_flag=TRUE;
    	}
    	//方案二
    	if(m_pThread)
         {
             ::TerminateThread(m_pThread->m_hThread,0);
             m_pThread=NULL;
         }
    }
    
    

    方案一处理的话,线程不会实时关闭,必须要到Sleep函数执行完毕才能通过关闭线程。但是是安全的,线程会销毁线程资源。

     

    方案二处理的话,线程能够实时关闭,但是不安全,线程资源不会销毁。 (资源释放与否是通过查看任务管理器中程序的内存使用)。

    有没有既安全又实时的结束线程方案?

    各位朋友发表下自己的想法,谢谢!

    2010年11月1日 9:55

答案

  • Sleep是不能被中断的

    你需要对你的程序重新设计


    但是这个Sleep是在一个线程里面的,结束掉线程就可以了。我的问题是出在怎么样安全结束线程?而且是一个处在Sleep的线程。TerminateThread固然可以,但是内存泄漏严重。

    没有什么更好的办法

    至少我不清楚

    线程最安全的结束方式就是自己结束

    可是sleep一旦启动就不会被停下来

    更何况你的sleep还是在线程里

    2010年11月3日 5:01

全部回复

  • 线程正常的return,不会导致内存使用增长。会恢复到未开启线程时的状态。

    但是使用::TerminateThread函数,内存使用就不断增加,不会恢复到未开启线程时的状态。

    反复点击开始和结束按钮,内存使用将一直增加。

    希望各位路过的朋友帮忙指点指点。先谢谢了!

    2010年11月1日 10:12
  • 我一般的做法是用方案1

    不过Sleep的时间调的小一些

    2010年11月1日 12:34
  • 不要用sleep也不要用一个全局变量,你可以在循环中用WaitForSingleObject等一个事件。在按钮按下的时候用SetEvent触发这个事件。这样用WaitForSingleObject中设置的timeout来挂起线程。
    麻烦把正确答案设为解答。
    2010年11月2日 7:37
    版主
  • 谢谢MVP向立天和版主SplendourG的回复。  方案1确实是安全的,但是对我现有的项目来说不适用。

    WaitForSingleObject这种事件方法也不适用。

    主要是我的解析器里面延时处理用了Sleep这个函数。所以当我脚本写上delay(10000)时,实际上就是执行了::Sleep(10000)的操作。

    基于此,我才想知道,怎样才能强制结束这个::Sleep操作的线程,而且是安全地结束。

    -----脚本执行是新开的线程处理。

    2010年11月3日 2:21
  • Sleep是不能被中断的

    你需要对你的程序重新设计

    2010年11月3日 2:39
  • Sleep是不能被中断的

    你需要对你的程序重新设计


    但是这个Sleep是在一个线程里面的,结束掉线程就可以了。我的问题是出在怎么样安全结束线程?而且是一个处在Sleep的线程。TerminateThread固然可以,但是内存泄漏严重。
    2010年11月3日 3:04
  • Sleep是不能被中断的

    你需要对你的程序重新设计


    但是这个Sleep是在一个线程里面的,结束掉线程就可以了。我的问题是出在怎么样安全结束线程?而且是一个处在Sleep的线程。TerminateThread固然可以,但是内存泄漏严重。

    没有什么更好的办法

    至少我不清楚

    线程最安全的结束方式就是自己结束

    可是sleep一旦启动就不会被停下来

    更何况你的sleep还是在线程里

    2010年11月3日 5:01
  • 谢谢向立天MVP对我问题的关注。

    现在的处理是线程自己退出,通过全局变量来的。之后再用WaitForSingleObject等待线程是否结束,1s之后线程没结束。就调用TerminateThread强制退出。

    这真的是没办法的办法了。

    2010年11月3日 7:14
  • Terminate thread is dangerous, may cause your application to have unpredictable behavior, for instance, if the to-be-terminated thread is allocating memory and has acquired the lock, then, the future heap allocation will be broken, also the resource reclamation also has the problem.

     

    Sleep cannot be interrupted, but SleepEx can be. But anyway, this is not a good way. Consider other good threads coordination method.

     

    2011年8月4日 0:35
  • 能将delay分为多段执行么?

     


    麻烦把正确答案设为解答。
    2011年8月4日 3:53
    版主
  • 用SleepEx(millionSeconds,TRUE)即可,需要退出时QueueUserAPC并发送一个什么也不做的回调函数。
    MaRs``
    • 已建议为答案 MaRs`` 2011年8月11日 6:58
    2011年8月11日 6:57