类是这样设计的
void myclass::StartThread(LPVOID lparam)
{
if (m_bol_run == TRUE) {
return;
} m_bol_run = TRUE;
CWinThread * p = AfxBeginThread(EncryptOrDencryptionThread , lparam);
m_handle_ptr = &p->m_hThread;
}void myclass::EndThread()
{
if (m_bol_run == FALSE) {
return;
}

m_bol_run = FALSE;
}至于线程函数就是循环加密文件 每次读入一部分字节进行加密 每次加密都回判断这个M_BOL_RUN 如果FALSE就BREAK循环
开机加密按钮启动STARTTHREAD函数 开始线程 停止按钮则执行ENDTHREAD函数 如果我不是退出程序 点击停止按钮 函数可以正常退出
但是如果我退出主程序 在OnCancle函数里执行EndThread函数 最后退出 有时会出现错误提示 就是那些没正常退出的错误框
但是我在ONCANCLE里用WaitForSingleObject就会死掉
我甚至将ENDTHREAD写成这样也不行 这样写连停止按钮一点就死掉
写法如下
void myclass::EndThread()
{
if (m_bol_run == FALSE) {
return;
}

m_bol_run = FALSE;        WaitForSingleObject(*m_handle_ptr , INFINITE);
}怎么办啊 我尝试在Oncancle里执行TerminatThread 但是程序是退出了 但是任务管理器里还有我的进程 也就是说进程退出了 但是线程还在运行 所以不打算用这个方法
WaitForSingleObject为什么会死啊 为什么

解决方案 »

  1.   

    你管加密的线程中有没有方法来知道 由于OnCancle被调用 线程应该被结束呢
    如果没有 可能是 他一直作自己的加密 由于你进程退了 他大概是会被TerminateThread
    后一种情况WaitForSingleObject(*m_handle_ptr , INFINITE);可能是线程一直没跑结束
    所以估计是你的线程函数中执行的时间很长又没有消息循环之类机制来获得通知或者死锁了
      

  2.   

    这样的;你要用个停止标志;
    比如m_bStop;一般的时候设成false;如果需要停止,就把m_bStop设成true;
    在线程中每个循环都判断m_bStop,一旦是true,就跳出线程的循环;这样写
    int myclass::EndThread()
    {
    m_bStop = true;
    WaitForSingleObject(*m_handle_ptr , INFINITE); return TRUE;
    }
      

  3.   

    你的加密线程是不是收到m_bool_run就马上退出?
      

  4.   

    我不是说M_BOL_RUN判断是否退出吗 楼上的明白我意思了 我是立刻退出的啊
      

  5.   

    两个问题:
    第一个问题, 用 if (m_bol_run) 方式检测,不够及时。通常已经 m_bol_run = false 半天了, 线程还在忙于上一次成功检测m_bol_run之后的加解密任务中。所以用m_bol_run = false 来结束线程,如果时间充足(如不关闭程序只点击停止按钮),都没问题。一旦时间紧迫(如程序退出时,设置m_bol_run之后程序立刻退出了),线程的麻烦就大了。
    解决方式也很多,比如,更频繁的检测,使用Event而不是BOOL,退出前等待等。
    第二个问题:
    貌似线程间还有互相相关的问题(wait死锁意味着ui等待线程的同时线程也在等待ui)。这个就不好说了,只能说线程运行模式要小心设计,不能图简单。
    根据楼主提供的这些信息,这里提供一个绕行的解决方法。这个方法不是最好的,但是应该管用。最好的方式还是重新规划一下线程的模型。
    原理很简单,就是用消息的方式跳过wait死锁部分,知道线程真正退出,才接续下一步的结束代码。 示意如下:CYouDialog::OnCanel()
    {
      static int n = 0;
      if (0 == n)  
      {
        n++;
        m_bol_run = false;
        PostMessage(WM_COMMAND, IDCANCEL);
        return;
      }
      if (1 == n)
      {
        checkthreadexitcode
        if (!completed)
          {
            PostMessage(WM_COMMAND, IDCANCEL);
            return;
          }
        else
          CDialog::OnCancel();
          现在安全了,继续下一步的退出代码......
      }
    }