工作者线程结束问题

slowly507 2019-01-18 09:51:10
大致描述一下:我在界面上有两个按钮,“开始”和“结束”,点击开始就启动一个工作者线程(这个线程一直在循环处理事情),点击结束就关闭该线程。代码框架大致如下。
【问题】点击结束,有时能正常结束线程,有时就没有响应了,程序忙。

void CDetcApplicationDlg::OnBnClickedStart()
{
g_bExtiThread = false; //停止状态为假
//..........省略代码.........
pThread = AfxBeginThread(threadFun, this,0,0, CREATE_SUSPENDED); //创建threadFun处理线程
if (pThread)
{
pThread->m_bAutoDelete = false;
pThread->ResumeThread();
}
}
void CDetcApplicationDlg::OnBnClickedStop()
{

if (pThread)
{
g_bExtiThread = true; //停止状态为真
if (WAIT_OBJECT_0 == WaitForSingleObject(pThread->m_hThread,INFINITE)) //等待线程结束,偶发结束线程失败

pThread = NULL; //将线程指针置为空

}
}

UINT CDetcApplicationDlg::threadFun(LPVOID lpParam)
{
CDetcApplicationDlg * pDlg = (CDetcApplicationDlg *)lpParam;
while(1)
{
if (g_bExtiThread)
{
AfxEndThread(0);
return 0;

}
//..........省略代码.........除了后台的处理工作,还更新一个listctrl的值
}
return 0;
}





...全文
885 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
tiger波波 2019-01-26
  • 打赏
  • 举报
回复
引用 14 楼 slowly507 的回复:
[quote=引用 12 楼 tiger波波 的回复:] 点击结束按钮时,对话框会死等线程;同时,线程里又要对话框更新数据,否则无法往下执行去判断是否结束的变量,陷入两边互等的锁死情况。而且你的线程里是全速执行,貌似没有Sleep,CPU会很忙。 最好用消息控制刷新界面,而且得使用postmessage,因为sendmessage一样会死等界面响应。
如果使用消息的方式,子线程里大概每处理约300ms就需要发送消息去让界面的其中两个控件更新,这样主线程会不会陷入繁忙的处理中?[/quote] 300ms不会,我试过50毫秒以上都没问题。或者你用事件也行,线程这边要更新就使能事件,界面那边定时查询事件,有效就更新界面,同时复位事件,然后再查询。
slowly507 2019-01-24
  • 打赏
  • 举报
回复
引用 12 楼 tiger波波 的回复:
点击结束按钮时,对话框会死等线程;同时,线程里又要对话框更新数据,否则无法往下执行去判断是否结束的变量,陷入两边互等的锁死情况。而且你的线程里是全速执行,貌似没有Sleep,CPU会很忙。 最好用消息控制刷新界面,而且得使用postmessage,因为sendmessage一样会死等界面响应。
我目前的子线程中,是有sleep函数的。
slowly507 2019-01-24
  • 打赏
  • 举报
回复
引用 12 楼 tiger波波 的回复:
点击结束按钮时,对话框会死等线程;同时,线程里又要对话框更新数据,否则无法往下执行去判断是否结束的变量,陷入两边互等的锁死情况。而且你的线程里是全速执行,貌似没有Sleep,CPU会很忙。 最好用消息控制刷新界面,而且得使用postmessage,因为sendmessage一样会死等界面响应。
如果使用消息的方式,子线程里大概每处理约300ms就需要发送消息去让界面的其中两个控件更新,这样主线程会不会陷入繁忙的处理中?
tiger波波 2019-01-23
  • 打赏
  • 举报
回复
点击结束按钮时,对话框会死等线程;同时,线程里又要对话框更新数据,否则无法往下执行去判断是否结束的变量,陷入两边互等的锁死情况。而且你的线程里是全速执行,貌似没有Sleep,CPU会很忙。 最好用消息控制刷新界面,而且得使用postmessage,因为sendmessage一样会死等界面响应。
sevancheng 2019-01-22
  • 打赏
  • 举报
回复
线程中发消息给对话框吧
woshi_hujunjun 2019-01-19
  • 打赏
  • 举报
回复
如果你想在UI中等待而不阻断消息可以加两句代码
static MSG msg;
if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
//发消息
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
woshi_hujunjun 2019-01-19
  • 打赏
  • 举报
回复

1. WaitForSingleObject会堵塞主线程,造成界面卡死
2. if (g_bExtiThread)
{
AfxEndThread(0);
return 0;

}
直接返回就好了, AfxEndThread(0);是多余的操作,而且可能引起不必要的问题
zgl7903 2019-01-18
  • 打赏
  • 举报
回复
这一句屏蔽掉试试看 if (WAIT_OBJECT_0 == WaitForSingleObject(pThread->m_hThread,INFINITE))
怀疑是阻塞了消息环

slowly507 2019-01-18
  • 打赏
  • 举报
回复
请问该怎么处理呢?在这个工作线程里,我需要更新一些控件的显示。
slowly507 2019-01-18
  • 打赏
  • 举报
回复
【补充】在线程函数中,下面的这段代码更新一个标签和一个表格控件,如果把这段代码去掉,线程就能正常结束! UINT CDetcApplicationDlg::threadFun(LPVOID lpParam) { CDetcApplicationDlg * pDlg = (CDetcApplicationDlg *)lpParam; while(1) { if (g_bExtiThread) { AfxEndThread(0); return 0; } //.这段代码更新一个标签和一个表格控件,如果把这段代码去掉,线程就能正常结束! ::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_RES), dectType); for (int i = 0; i <= 11; i++)//更新表格控件 { CString itemCount; CString itemPercent; itemCount.Format(_T("%d"), g_proCount[i]); itemPercent.Format(_T("%.2f%%"), (double)g_proCount[i] / g_total * 100); pDlg->m_lstRet.SetItemText(i, 2, itemCount); pDlg->m_lstRet.SetItemText(i, 3, itemPercent); } } return 0; }
slowly507 2019-01-18
  • 打赏
  • 举报
回复
引用 3 楼 schlafenhamster 的回复:
void CDetcApplicationDlg::OnBnClickedStop() { g_bExtiThread=TRUE; Sleep(0);// let thread runs ! }
试了,也不行
schlafenhamster 2019-01-18
  • 打赏
  • 举报
回复
while(!g_bExtiThread)
{
//..........省略代码.........除了后台的处理工作,还更新一个listctrl的值
}
retun 0;


void CDetcApplicationDlg::OnBnClickedStop()
{
g_bExtiThread=TRUE;
Sleep(0);// let thread runs !
}
slowly507 2019-01-18
  • 打赏
  • 举报
回复
引用 1 楼 schlafenhamster 的回复:
volatile BOOL g_bExtiThread;
我确实是这样定义的。
schlafenhamster 2019-01-18
  • 打赏
  • 举报
回复
volatile BOOL g_bExtiThread;
schlafenhamster 2019-01-18
  • 打赏
  • 举报
回复
pThread->m_bAutoDelete = false;
不要 改 pThread->m_bAutoDelete ; (默认 TRUE)
这是 用 g_bExtiThread 的 基础 !

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧