关于强制终止线程的问题

coloriy 2010-08-03 11:32:12
自己开发的动态库 提供的CaptureEnd函数,
在内部实现停止处理线程A,该处理线程A通过回调函数方式把dll库中的数据传给用户,供用户使用,停止过程中,如果用户处理过慢,在停止函数过程中,想要实现如下功能:
如果线程A在执行用户回调函数过程中,用户回调函数长时间不返回,则强行杀掉该线程TiminalThread该线程,结果发现有内存泄露,
请问有什么方法可以实现该策略。
目前做法:
CSnap::CaptureEnd函数中,驱动消息循环结束线程。
DWORD dwExit = 0;
MSG msg;
int nCount = 0;
do
{
Sleep(1);
GetExitCodeThread(m_pProcessTread->GetThreadHandle(), &dwExit);
if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
if (nCount > 2000000)
{
m_pProcessTread->Terminate(0);
}
nCount++;

} while( dwExit == STILL_ACTIVE );
m_pProcessTread->CloseThreadHandle();



另一个函数导出接口函数DeviceClose中,销毁该线程所在的对象CSnap, delete m_pSnap.


如果在一个按钮调用CaptureEnd后,点击另一个按钮调用DeviceClose过快,即不等待captureEnd函数执行完,就执行DeviceClose,则销毁对象先执行,导致CSnap中的m_pProcessThread对象失效,而报错。

如果直接强杀掉该线程,然后DeviceClose销毁该对象,则内存泄露。

后来尝试在CaptureEnd 中加互斥段,结果因为是单线程,互斥段失效,现无别的招,请教高手。
...全文
848 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
coloriy 2010-08-03
  • 打赏
  • 举报
回复
再次声明,Event事件方式,互斥段等都是在多线程中起作用,在单线程中,都不起作用,这个已经验证
coloriy 2010-08-03
  • 打赏
  • 举报
回复
是这样的:
captureEnd: do while 驱动消息,等待线程退出,退出后设置标志m_bCaptureStop = ture

DeviceClose: delete CSnap对象,在CSnap的析构中判断m_bCaptureStop,如果为false,则执行captureEnd,结果captureEnd中的互斥段变量不起作用,总是能够重入captureend,后来发现互斥段变量在一个线程中不起作用。

该方法失败。

其实逻辑很简单:
就是想在captureEnd函数执行完毕后,在执行DeviceClose,销毁采集对象CSnap

但是由于captureEnd函数内部停止线程时采用了消息驱动方式,do while方式,
界面上在点击captureEnd函数后,不会阻塞,直到该函数执行,因此,当用户再次点击Deviceclose 的按钮时, deviceClose就会被执行,此时,CaptureEnd函数还没有执行完,而DeviceClose就给执行了,导致Snap对象失效,CaptureEnd函数就会出错。
coloriy 2010-08-03
  • 打赏
  • 举报
回复
因为是在同一个线程,waitforsingleobject 总是超时,等不到的
draculamx 2010-08-03
  • 打赏
  • 举报
回复
用 message 处理一下
hslinux 2010-08-03
  • 打赏
  • 举报
回复
能不能通过EVENT来同步下操作?
DeviceClose中,WaitForSingleObject()等待EVENT被设置,等待超时可以考虑强制杀掉线程;
线程函数中退出之前SetEvent();
  • 打赏
  • 举报
回复
WaitForSingleObject
coloriy 2010-08-03
  • 打赏
  • 举报
回复
7楼兄弟captureEnd中不能做清理消息,因为该函数属于对象CSnap,而CSnap采集对象是归设备管理的,CDeivce调用DEviceClose接口来删除CSnap对象,CaptureEnd只是结束采集线程,但是消灭该对象是设备层管的,所以不行。

后来我们项目组决定实在不行只能在CaptureEnd中强杀TerminalThread了,也不等用户的回调返回了,也不等线程退出了,只要用户占着回调函数不返回,do-while消息驱动200次后,就TerminalThread掉线程。

然后用户再点击DeviceClose就ok了,至少不报错,虽然有内存泄露。

8楼兄弟taodm是正解。
taodm 2010-08-03
  • 打赏
  • 举报
回复
都强杀线程了,就不用讨论内存泄漏问题了,没啥意思了,忍到进程结束就行了。
hslinux 2010-08-03
  • 打赏
  • 举报
回复

所有清理操作在CaptureEnd()中执行可以不?

DeviceClose()的时候,发个消息给CaptureEnd()要求强制退出:我等得不耐烦了,你TMD别墨迹了马上退出;

CaptureEnd()收到消息就强制退出,并清理数据;

CaptureEnd()正常退出的时候也清理数据。

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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