如何关闭正在阻塞的子线程

自娱自乐。 2020-04-17 01:15:43
子线程就是进行网络连接,然后就一直等待接收数据,可以正常实现接收功能,但是在关闭程序的时候会报错内存泄漏,猜测原因是recv,是个阻塞函数,在主程序的onclose中发送关闭子程序的标志位和发送自定义关闭消息两种方式,都不能进入到子线程中去关闭,也试过sleep一定时间,请问有什么好的方式,关闭正在阻塞的子线程?

UINT MyThreadProc(LPVOID pParam)
{
char buff[2000];
int n;
SOCKET Client = ((RECVPARAM*)pParam)->sock;
HWND hWnd = ((RECVPARAM*)pParam)->hwnd;
SOCKADDR_IN Addr = ((RECVPARAM*)pParam)->addr;

if (SOCKET_ERROR == connect(Client, (SOCKADDR*)&Addr, sizeof(SOCKADDR)))
{
int nError = WSAGetLastError();
CString strErrorMsg;
SendMessage(hWnd, WM_NETERROR, 0, 0);
return FALSE;
}
::SendMessage(hWnd, WM_NETCONNECTED, 0, 0);//网络连接成功

while (TRUE)
{
memset(buff, 0, sizeof(buff));
n = recv(Client, buff, sizeof(buff), 0);//阻塞,n是拷贝的字节数
if (n == 0)//网络连接断开时,例如关闭服务器
{
SendMessage(hWnd, WM_NETERROR, 0, 0);
return 0;
}
if (n == SOCKET_ERROR)
{
SendMessage(hWnd, WM_NETERROR, 0, 0);
return 0;
}
::SendMessage(hWnd, WM_RECVDATA, (WPARAM)n, (LPARAM)buff);
}
return TRUE;
}
...全文
1325 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
tiger波波 2021-01-15
  • 打赏
  • 举报
回复
阻塞模式你主动close服务器端socket,recv应该也会立即返回吧,应该是-1,这时你再判断下线程退出标志位就行了 https://blog.csdn.net/wainiwann/article/details/38978135
gz_qmc 2021-01-15
  • 打赏
  • 举报
回复
你这个不是接收发送阻塞
你这是SendMessage阻塞
就是典型的便秘
simple 2021-01-14
  • 打赏
  • 举报
回复
采用非阻塞socket,然后一直recv,设置控制线程结束的变量status,当status为0的时候就退出线程。
an_bachelor 2021-01-06
  • 打赏
  • 举报
回复
你可以在协议中设计一种“结束等待”的消息, 并由主控线程在退出服务之前给你的子线程(正阻塞在recv)发这个消息。 子线程可以作一快速检测,例如根据包中的某个标志来判断是否收了就不再继续recv,而是shudown、closesocket, 不要让子线程只能不分任何情况地重新recv,这个判断是很快的,通常不会影响到跑满带宽。
cyhbitter 2021-01-06
  • 打赏
  • 举报
回复
楼主找到解决方法了吗,我也遇到了类似的问题
hhhh63 2020-04-19
  • 打赏
  • 举报
回复
主线程中加一行
WaitForSingleObject(m_pThread->m_hThread, 500); // 等待线程结束
zgl7903 2020-04-17
  • 打赏
  • 举报
回复
推荐 ioctlsocket FIONBIO 异步模式,
这样就有机会检测退出标记了

自娱自乐。 2020-04-17
  • 打赏
  • 举报
回复
引用 3 楼 smwhotjay 的回复:
优雅的关闭socket.
请问具体怎么操作?
smwhotjay 2020-04-17
  • 打赏
  • 举报
回复

优雅的关闭socket.
自娱自乐。 2020-04-17
  • 打赏
  • 举报
回复
强制杀死线程会导致内存泄漏 Detected memory leaks! Dumping objects -> f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\thrdcore.cpp(306) : {369} client block at 0x00D45DD8, subtype c0, 68 bytes long. f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\dumpcont.cpp(23) : atlTraceGeneral - a CWinThread object at $00D45DD8, 68 bytes long 我设置了一个全局的标志位,在关闭主窗口时将标志位设置为true,在while中判断标志若为true就return,但是调试发现标志位设置成功了,但是却不进入到子线程中去就直接退出了程序,依旧内存泄漏
hhhh63 2020-04-17
  • 打赏
  • 举报
回复
最好的办法是结束循环,退出线程。设一个标识,子线程中碰到标志就退出,等所有线程都退出了再退出主进程
if (theApp.m_mutexExit.isLocked()) //正在退出,中断
return;

也可以强行杀死线程
m_pThread->m_bAutoDelete = TRUE;
DWORD ExitCode;
GetExitCodeThread(m_pThread->m_hThread, &ExitCode);
TerminateThread(m_pThread->m_hThread, ExitCode);

15,473

社区成员

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

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