随笔 - 41  文章 - 2 评论 - 0 阅读 - 52537
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

在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);
}
复制代码

如此就可以安全的退出阻塞的子线程。

 

posted on   lazybee  阅读(592)  评论(0编辑  收藏  举报
编辑推荐:
· 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训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示