windows下线程退出,不导致内存泄露

hysea2006 2014-04-28 10:00:39
我在CTrayDlg中开启一个线程:
m_hThread = CreateThread(NULL, 0, ThreadFunc, this, 0, &m_dwThreadID);
线程执行函数为
static DWORD WINAPI ThreadFunc(LPVOID lParam)
{
CTrayDlg *pDlg = (CTrayDlg*)lParam;
while(pDlg->m_bRunning)
{
...............................................
}

return pDlg->m_dwThreadID;
}

当我在CTrayDlg中设置m_bRunning为false,然后用GetExitCodeThread(m_hThread, &dwThreadID);
dwThreadID的值始终都是STILL_ACTIVE,获取不到线程函数退出时返回的 pDlg->m_dwThreadID,为什么啊?
我是这么实现的:
DWORD dwThreadID = STILL_ACTIVE;
while (dwThreadID != m_dwThreadID)
{
GetExitCodeThread(m_hThread, &dwThreadID);
Sleep(1000);
}
一直在循环里面。
...全文
315 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
hysea2006 2014-04-30
  • 打赏
  • 举报
回复
可以获取到了,是不小心在之前将线程句柄关闭了................................
schlafenhamster 2014-04-29
  • 打赏
  • 举报
回复
static DWORD WINAPI ThreadFunc(LPVOID lParam) { CTrayDlg *pDlg = (CTrayDlg*)lParam; while(pDlg->m_bRunning) {// volatile 在这里起作用,防止 编译器 把 他 放入 “寄存器” 中 测试 ! ............................................... } return pDlg->m_dwThreadID; }
Jarrylogin 2014-04-29
  • 打赏
  • 举报
回复
引用 13 楼 Jarrylogin 的回复:
[quote=引用 12 楼 hysea2006 的回复:] DWORD dwThreadID = STILL_ACTIVE; while (dwThreadID != m_dwThreadID) =====> while (dwThreadID == STILL_ACTIVE) { GetExitCodeThread(m_hThread, &dwThreadID); Sleep(1000); } 是这个原因吧!!!
不行的!!![/quote] 你的代码添加位置可能有问题!! 还是我这段代码, 你把它放到 CTrayDlg中开启一个线程: m_hThread = CreateThread(NULL, 0, ThreadFunc, this, 0, &m_dwThreadID); 在这后面添加: Sleep(1000); m_bRunning=FALSE; for (;;) { GetExitCodeThread(m_hThread, &dwThreadID); Sleep(1000); if ( dwThreadID != STILL_ACTIVE ) break; } 再看看是否有问题? [/quote] m_hThread = CreateThread(NULL, 0, ThreadFunc, this, 0, &m_dwThreadID); for (;;) { GetExitCodeThread(m_hThread, &dwThreadID); Sleep(1000); if ( dwThreadID != STILL_ACTIVE ) break; } volatile 关键字 如果是第一次m_bRunning=FALSE赋值,肯定是从硬盘上读取,也就没有必要加。 我本意是让他在看看线程的返回值变化了没有,我的这段代码是msdn的,应该没有问题。
Jarrylogin 2014-04-29
  • 打赏
  • 举报
回复
当然,从代码的健壮性来说: 我写代码是需要加 volatile 的,也可能直接用CEvent了
Jarrylogin 2014-04-29
  • 打赏
  • 举报
回复
引用 18 楼 schlafenhamster 的回复:
static DWORD WINAPI ThreadFunc(LPVOID lParam) { CTrayDlg *pDlg = (CTrayDlg*)lParam; while(pDlg->m_bRunning) {// volatile 在这里起作用,防止 编译器 把 他 放入 “寄存器” 中 测试 ! ............................................... } return pDlg->m_dwThreadID; }
volatile本意是防止编译器 进行优化,(并不代码 所有的编译器都 放到“寄存器”优化) 就楼主的描述来说:它的代码是能够退出的,也就是while(pDlg->m_bRunning) 能跳出来。所以从实际情况看,也不一定用的上。
hysea2006 2014-04-28
  • 打赏
  • 举报
回复
引用 9 楼 hysea2006 的回复:
void CTrayDlg::OnDestroy() { CDialogEx::OnDestroy(); // TODO: 在此处添加消息处理程序代码 if (INVALID_HANDLE_VALUE != m_hThread) { //m_bRunning = false; Sleep(1000); DWORD dwThreadID = STILL_ACTIVE; while (dwThreadID == STILL_ACTIVE) { GetExitCodeThread(m_hThread, &dwThreadID); Sleep(1000); } CloseHandle(m_hThread); }
void CTrayDlg::OnDestroy() { CDialogEx::OnDestroy(); // TODO: 在此处添加消息处理程序代码 if (INVALID_HANDLE_VALUE != m_hThread) { m_bRunning = false; Sleep(1000); DWORD dwThreadID = STILL_ACTIVE; while (dwThreadID == STILL_ACTIVE) { GetExitCodeThread(m_hThread, &dwThreadID); Sleep(1000); } CloseHandle(m_hThread); }
hysea2006 2014-04-28
  • 打赏
  • 举报
回复
void CTrayDlg::OnDestroy() { CDialogEx::OnDestroy(); // TODO: 在此处添加消息处理程序代码 if (INVALID_HANDLE_VALUE != m_hThread) { //m_bRunning = false; Sleep(1000); DWORD dwThreadID = STILL_ACTIVE; while (dwThreadID == STILL_ACTIVE) { GetExitCodeThread(m_hThread, &dwThreadID); Sleep(1000); } CloseHandle(m_hThread); }
Jarrylogin 2014-04-28
  • 打赏
  • 举报
回复
这段代码你加在什么位置?把上下文贴一下
Jarrylogin 2014-04-28
  • 打赏
  • 举报
回复
引用 5 楼 hysea2006 的回复:
CTrayDlg *pDlg是有效的,MFC非线程函数是什么意思?
你确定你的这段代码没有问题吗? DWORD dwThreadID = STILL_ACTIVE; while (dwThreadID != m_dwThreadID) { GetExitCodeThread(m_hThread, &dwThreadID); Sleep(1000); }
hysea2006 2014-04-28
  • 打赏
  • 举报
回复
引用 3 楼 Jarrylogin 的回复:
用我的代码替换一下: for (;;) { GetExitCodeThread(m_hThread, &dwThreadID); Sleep(1000); if ( dwThreadID != STILL_ACTIVE ) break; }
还是一样啊!!!
hysea2006 2014-04-28
  • 打赏
  • 举报
回复
CTrayDlg *pDlg是有效的,MFC非线程函数是什么意思?
Eleven 2014-04-28
  • 打赏
  • 举报
回复
你线程中得到的CTrayDlg *pDlg这个值有效??MFC非线程函数,你不应该将MFC中窗口类的指针作为线程函数的参数传递给线程。
Jarrylogin 2014-04-28
  • 打赏
  • 举报
回复
用我的代码替换一下: for (;;) { GetExitCodeThread(m_hThread, &dwThreadID); Sleep(1000); if ( dwThreadID != STILL_ACTIVE ) break; }
hysea2006 2014-04-28
  • 打赏
  • 举报
回复
可以退出的,我设置断点到return pDlg->m_dwThreadID;会返回值,线程执行函数退出,但是GetExitCodeThread(m_hThread, &dwThreadID)获取返回值,获取不到..................
Jarrylogin 2014-04-28
  • 打赏
  • 举报
回复
while(pDlg->m_bRunning) { ............................................... } 这个代码添加一下:看看是否能退出: while(pDlg->m_bRunning) { ............................................... pDlg->m_bRunning = false; }
schlafenhamster 2014-04-28
  • 打赏
  • 举报
回复
volatile BOOL m_bRunning; // void CxxxxDlg::OnButton1() { // TODO: Add your control notification handler code here m_bRunning=TRUE; m_hThread = CreateThread(NULL, 0, ThreadFunc, this, 0, &m_dwThreadID); //afxDump << m_dwThreadID << "\n";// 2752 Sleep(1000); m_bRunning=FALSE; // DWORD dwThreadID = STILL_ACTIVE; while (dwThreadID != m_dwThreadID) { GetExitCodeThread(m_hThread, &dwThreadID); Sleep(100); } if(m_dwThreadID == dwThreadID) AfxMessageBox("OK"); }
hysea2006 2014-04-28
  • 打赏
  • 举报
回复
我要的是线程的返回值!!!
hysea2006 2014-04-28
  • 打赏
  • 举报
回复
你的代码添加位置可能有问题!! 还是我这段代码, 你把它放到 CTrayDlg中开启一个线程: m_hThread = CreateThread(NULL, 0, ThreadFunc, this, 0, &m_dwThreadID); 在这后面添加: for (;;) { GetExitCodeThread(m_hThread, &dwThreadID); Sleep(1000); if ( dwThreadID != STILL_ACTIVE ) break; } 再看看是否有问题? [/quote] 算了,根本行不通。
Jarrylogin 2014-04-28
  • 打赏
  • 举报
回复
引用 12 楼 hysea2006 的回复:
DWORD dwThreadID = STILL_ACTIVE; while (dwThreadID != m_dwThreadID) =====> while (dwThreadID == STILL_ACTIVE) { GetExitCodeThread(m_hThread, &dwThreadID); Sleep(1000); } 是这个原因吧!!!
不行的!!![/quote] 你的代码添加位置可能有问题!! 还是我这段代码, 你把它放到 CTrayDlg中开启一个线程: m_hThread = CreateThread(NULL, 0, ThreadFunc, this, 0, &m_dwThreadID); 在这后面添加: for (;;) { GetExitCodeThread(m_hThread, &dwThreadID); Sleep(1000); if ( dwThreadID != STILL_ACTIVE ) break; } 再看看是否有问题?
hysea2006 2014-04-28
  • 打赏
  • 举报
回复
DWORD dwThreadID = STILL_ACTIVE; while (dwThreadID != m_dwThreadID) =====> while (dwThreadID == STILL_ACTIVE) { GetExitCodeThread(m_hThread, &dwThreadID); Sleep(1000); } 是这个原因吧!!! [/quote] 不行的!!!
加载更多回复(1)
内容概要:本文针对无刷直流电机驱动的电子机械制动(EMB)执行器,建立了考虑Stribeck摩擦特性的非线性耦合动力学模型,并在Simulink环境中完成了系统级仿真分析。研究综合集成了电机动力学、齿轮传动机构与制动执行机构的动力学特性,构建了高保真的机电一体化系统模型。重点引入Stribeck摩擦模型以精确描述低速工况下执行器内部存在的静摩擦、粘滞摩擦与库仑摩擦之间的过渡行为,有效提升了系统在启停、反向运动等瞬态过程中的动态响应仿真精度。通过多工况仿真验证了模型的有效性,能够准确反映摩擦引起的爬行、滞后与定位误差等非线性现象,为EMB系统的高性能控制算法设计(如摩擦补偿、滑模控制)与结构优化提供了高可信度的仿真平台。; 适合人群:从事汽车电子制动系统、电机驱动控制、机电系统建模与仿真研究的研究生、科研人员及工程技术人员,需具备扎实的机械动力学、自动控制理论基础和MATLAB/Simulink仿真能力。; 使用场景及目标:①用于高精度电子机械制动系统的设计验证与性能预测;②为消除摩擦非线性影响的先进控制策略(如自适应控制、智能控制)提供精确的被控对象模型;③深入探究Stribeck摩擦等非线性因素对系统动态性能(如响应延迟、稳态误差)的作用机理; 阅读建议:读者应结合提供的Simulink模型文件,深入剖析Stribeck摩擦模块的数学实现与参数辨识方法,建议通过改变输入指令(如阶跃、正弦)和负载条件进行对比仿真,以直观理解非线性摩擦对系统动态特性的影响。

15,465

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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