我先把我的代码大致发一下吧://这个函数是按钮的响应函数,负责生成一个搜索过程的子线程
void CResourceDlg::OnBnClickedBtnSearch()
{
// TODO: Add your control notification handler code here
CString strSearchTxt;
GetDlgItemText(IDC_EDIT_SEARCH, strSearchTxt);//这是搜索关键字 SearchState();//这个函数设置一个枚举值,表示可以搜索了 strSearchTxt = strSearchTxt.Trim();
if (strSearchTxt.IsEmpty())
{
return;
} if (m_hSearchThread)//定义的成员变量,接收搜索子线程的句柄
{
WaitForSingleObject(m_hSearchThread, INFINITE);
m_hSearchThread = NULL;
} CSearchProcess *pSearchProcess = new CSearchProcess(this, strSearchTxt);
CWinThread *pWinThread = AfxBeginThread(SearchResourceProc, static_cast<LPVOID>(pSearchProcess));
if (pWinThread)
{
m_hSearchThread = pWinThread->m_hThread;
}
}
//这个函数是一个按钮的响应函数,负责停止搜索过程
void CResourceDlg::OnBnClickedBtnClose()
{
// TODO: Add your control notification handler code here
NormalState();//把状态改成非搜索模式,这样,子线程里面就可以知道要退出搜索了
if (m_hSearchThread)
{
DWORD dwRet = WaitForSingleObject(m_hSearchThread, INFINITE);//这里就死掉了
ASSERT(dwRet == WAIT_OBJECT_0);
m_hSearchThread = NULL;
}
}
线程的函数代码可以确定是正确的。因为不点这个停止搜索按钮的时候,是可以正常搜索的。可是一点停止搜索,就死锁了。

解决方案 »

  1.   

    跟踪试试停止搜索是运行CResourceDlg::OnBnClickedBtnClose()这个吗
      

  2.   

    不要在主线程中用WaitForSingleObject(....,INFINITE)
      

  3.   

    LZ的意思是在线程关闭后还要做些后续操作?试试另外创建一个事件对象句柄CreateEvent(),等待它。
    因为你已经验证了等待那个线程句柄是不行的了。
      

  4.   

    SearchResourceProc里跑到return;这行了吗?TRACE过了没?
      

  5.   

    刚调了半天,问题我估计找到了,可是发现不好想解决办法。
    其实是这么一个模式:
    主线程中的这个搜索按钮点击后,生成一个搜索资源的子线程,而这个子线程要把结果写到一个控件上,这个控件是属于主线程的,只不过子线程中得到了它的指针,从而可以往它上面加东西。
    因此,在主线程中,如果点击停止搜索的按钮,像我代码中的那样,等待子线程的结束,从而主线程进入等待状态。此时,子线程获得CPU,但它要把搜索结果写到主线程上的控件中,由于主线程已经陷入等待状态,所以这个过程无法完成,反而让子线程也进入到等待状态了。这样就出现死锁了。我发现考虑用个事件内核对象也不太好解决问题呢,各位有什么好的办法吗?
      

  6.   

    子线程PostMessage发消息通知主线程,主线程去更新控件.
      

  7.   

    那你还是没有return嘛.
    改成postmessage来写吧.
      

  8.   

    我这里用PostMessage非常麻烦,这样要拆解数据。是否有其他办法?
      

  9.   


    数据可以作成全局的,PostMessage只做简单通知.
      

  10.   

    点一下按钮,你就EnableWindow(FALSE)掉不就行了
      

  11.   

    Sorry,我看错了,要看你线程函数里怎么做的
    不要在主线程中WaitForSingleObject()
      

  12.   

    我把我的问题说透彻点吧。我现在有个数据集合A,我现在要做个搜索功能。各位应该看过PPS的搜索功能,我要做的和这个类似。正常情况下,我这个数据集合中的数据是分条目显示在一个ListCtrl中的,这些条目对应于一个CTreeCtrl。比如,我点这个CTreeCtrl中的节点“中国”,那么这个CListCtrl就会显示中国的各个省份,而如果我点树控件的节点“美国”,那么CListCtrl就会给我把美国的各个州显示出来。
    一旦我输入某个关键字如“北京”,那么就要进行搜索,把搜索结果显示在这个CListCtrl中。同时,还可以随时停止搜索动作。而且,最好是我搜索的时候如果再次输入关键字,搜索过程能够放弃刚才正在做的搜索过程而开始重新搜索。
    部长说的采用子线程发送消息过来,我也想过,可是这个办法不好解决这样一个问题:我在搜索的时候,搜索还没结束,可点了停止搜索按钮,还是无法立刻停止子线程的搜索过程。除非在主线程中采用死循环不断判断子线程传回来的状态信息。
      

  13.   

    我在5L已经几乎说出了问题的关键——后续操作,如果不需要后续操作,
    那主线程就根本不需要等待工作线程结束。而按LZ自己的说法工作线程
    中又在调用主线程的控件即需要主线程控件的响应,所以导致死锁。可以试试换一种方式,在工作线程的末尾向主线程发送一个异步消息
    (PostMessage),主线程在这个消息中做后续处理。如果这样还不行,
    I'm afraid 你只能是再开一个监视线程了。另外,我不太明白你为什么不能直接杀线程(TerminateThread)。
      

  14.   

    处理主进程的东西不要放在子线程里面,这样容易出问题,然后可以在点击close的时候发消息,通知界面显示,“没有找到结果”。
    如果正确的找到了,就发送消息到主进程。总之,更改界面的操作都要放在主进程的消息处理里面,否则容易混乱。
    还可以加个定时器,规定时间内没有找到,定时的kill线程。具体是terminate,还是个什么玩意,你查吧。
    别忘记killtimer。
      

  15.   

    如果不是出现了大的问题,不要kill线程,但是如果非要kill ,就不能光考虑泄露了,没有办法了。要不就做一个线程内的操作,可以正确的结束运行中的线程,都不行了,再强行关闭。
      

  16.   

    我在想,如果我在子线程中把搜索的结果PostMessage到主线程的控件上,然后主线程等待子线程的结束。这样会不会造成阻塞呢?我试一下了再告诉各位。
      

  17.   

    WaitForSingleObject函数用来检测hHandle事件的信号状态,当函数的执行时间超过dwMilliseconds就返回,但如果参数dwMilliseconds为INFINITE时函数将直到相应时间事件变成有信号状态才返回,否则就一直等待下去,直到WaitForSingleObject有返回直才执行后面的代码