在MFC 中创建一个子线程, pThread=AfxBeginThread(ThreadRdNetServer,(LPVOID)this);当程序退出时,子线程被强制关闭,子程序的资源没有回收,会造成内存泄漏:
Detected memory leaks!
Dumping objects ->
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\thrdcore.cpp(306) : {83} client block at 0x01C98C00, subtype c0, 68 bytes long.
a CWinThread object at $01C98C00, 68 bytes long
解决这个问题,可以定义一个BOOL型的变量BOOL g_bThread = TRUE,作为子线程的循环条件,在主线程的退出函数里,用WaitForSingleObject获取线程状态,等待线程后,再退出程序:
void CXXXDlg::OnDestroy() { CDialog::OnDestroy(); g_bThread = FALSE; WaitForSingleObject(pThread->m_hThread,INFINITE); }
若子线程是TCP 的服务器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | SOCKET sockSrv; SOCKET sockConn; UINT CTcpServerDlg:: ThreadNetServer( LPVOID pParam) { ...... //创建用于监听的套接字 sockSrv = socket(AF_INET, SOCK_STREAM, 0); ...... while (g_bThread) { //等待客户端请求到来 sockConn = accept(sockSrv, (SOCKADDR *)&addrClient, &len); if (sockConn==INVALID_SOCKET) { continue ; } char recvBuf[100]={ '\0' }; recv(sockConn, recvBuf, 100, 0); //接受数据 ...... } closesocket(sockSrv); //关闭监听套接字 WSACleanup(); // 卸载winsock library } |
线程会阻塞在函数accept 、 recv 处;即使循环条件g_bThread = FALSE, 因为线程阻塞也无法跳出循环,这个时候若是关闭对话框,会阻塞在函数 WaitForSingleObject无法退出
解决方法:要使程序从accept 中返回,可以在主程序中关闭监听套接字sockSrv;这样accept 返回INVALID_SOCKET,执行continue,此时条件不成立从而跳出循环,结束子线程;
void CTcpServerDlg::OnDestroy() { CDialog::OnDestroy(); // TODO: Add your message handler code here //结束子线程 closesocket(sockSrv); g_bThread = FALSE; WaitForSingleObject(pThread->m_hThread,INFINITE); }
如此就可以安全的退出阻塞的子线程。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人