BOOL Interface::Listen()
{
m_bLoop = TRUE; DWORD dwThreadID;
m_hListenerThread = ::CreateThread(
(LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)_threadProc,
this,
0,
&dwThreadID
);
if (m_hListenerThread == INVALID_HANDLE_VALUE) {
m_bLoop = FALSE;
goto _err;
}
return TRUE;_err: if (m_hDevice) {
CloseHandle(m_hDevice);
m_hDevice = NULL;
}
return FALSE;
}/*!
\brief Abort Listenning for Interface. \param lpszName [in] Device Name. \retval TRUE Success.
\retval FALSE Failure.
*/
void Interface::Abort()
{
m_bLoop = FALSE;
FUNC_START_LOG("Abort");
if (m_hListenerThread)
{
::WaitForSingleObject(m_hListenerThread, 10000);
FUNC_END_LOG("Abort"); ::CloseHandle(m_hListenerThread);
m_hListenerThread = NULL;
}
}DWORD WINAPI Interface::_threadProc(void *pObject)
{
Interface *pThis = (Interface*)pObject;
return pThis->_listenerLoop();
}DWORD Interface::_listenerLoop()
{
BYTE report[256];
REPORT decrep; FUNC_START_LOG("listenerLoop");
while (m_bLoop)
{
DWORD dwLen = _readReport(report, sizeof(report), 30000);
if (dwLen > 0) {
memset(&decrep, 0, sizeof(decrep));
if (_decodeReport(&decrep, report, dwLen)) {
if (m_pSignPad) m_pSignPad->onReceive(&decrep);
}
}
}
FUNC_END_LOG("listenerLoop");
return 0;
}1.abort函数中,m_bLoop = FALSE;这个变量改变,并没有使_listenerLoop()函数while循环立即结束,也就导致了::WaitForSingleObject(m_hListenerThread, 10000);等待失败。直接closehandle其句柄,可能有什么异常呢?1。我的问题是怎么在Abort中合理地终止线程,或者_listenerLoop()函数怎么更加合理些?该程序还有其他不合理的地方吗?2. 在c++运行库中直接调用createthead函数会导致内存泄露,是这样子的吗?
{
m_bLoop = TRUE; DWORD dwThreadID;
m_hListenerThread = ::CreateThread(
(LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)_threadProc,
this,
0,
&dwThreadID
);
if (m_hListenerThread == INVALID_HANDLE_VALUE) {
m_bLoop = FALSE;
goto _err;
}
return TRUE;_err: if (m_hDevice) {
CloseHandle(m_hDevice);
m_hDevice = NULL;
}
return FALSE;
}/*!
\brief Abort Listenning for Interface. \param lpszName [in] Device Name. \retval TRUE Success.
\retval FALSE Failure.
*/
void Interface::Abort()
{
m_bLoop = FALSE;
FUNC_START_LOG("Abort");
if (m_hListenerThread)
{
::WaitForSingleObject(m_hListenerThread, 10000);
FUNC_END_LOG("Abort"); ::CloseHandle(m_hListenerThread);
m_hListenerThread = NULL;
}
}DWORD WINAPI Interface::_threadProc(void *pObject)
{
Interface *pThis = (Interface*)pObject;
return pThis->_listenerLoop();
}DWORD Interface::_listenerLoop()
{
BYTE report[256];
REPORT decrep; FUNC_START_LOG("listenerLoop");
while (m_bLoop)
{
DWORD dwLen = _readReport(report, sizeof(report), 30000);
if (dwLen > 0) {
memset(&decrep, 0, sizeof(decrep));
if (_decodeReport(&decrep, report, dwLen)) {
if (m_pSignPad) m_pSignPad->onReceive(&decrep);
}
}
}
FUNC_END_LOG("listenerLoop");
return 0;
}1.abort函数中,m_bLoop = FALSE;这个变量改变,并没有使_listenerLoop()函数while循环立即结束,也就导致了::WaitForSingleObject(m_hListenerThread, 10000);等待失败。直接closehandle其句柄,可能有什么异常呢?1。我的问题是怎么在Abort中合理地终止线程,或者_listenerLoop()函数怎么更加合理些?该程序还有其他不合理的地方吗?2. 在c++运行库中直接调用createthead函数会导致内存泄露,是这样子的吗?
解决方案 »
- 今天正式失业,散分
- 使用API显示位图资源的问题(在线等)
- SDI窗口中,如何在不丢失已画出的图形的前提下,更改背景色呢?
- memcpy有可能出现内存泄漏?
- VC打印问题
- 求《应用程序调试》和 《windows程序调试》的电子版,第一个有效连接给分!
- 如何把Word文件转成一系列图片(要求打印输出效果与原文件相同)
- 用程序代替OutLook进行邮件合并,需要注意什么特殊规则,那里可以找到这方面的资料,希望有做过的高手详谈一下。
- 如何防止在CFileDialog中删除文件和文件夹??
- csdn终于好了, 问个com注册方面的问题
- 关于基于opencv开发视频播放器
- VC调用WebService,如何接收复杂点的服务返回参数!
2.木有这么一说吧
DWORD dwLen = _readReport(report, sizeof(report), 30000);如果 每次loop执行时间大于10000,导致 wait 失败或是超时多线程对m_bLoop处理,最好加上同步机制
经过日志发现,Abort中的m_bLoop变量改变并没有使线程自动退出。。
11:04:31 4456500 start Disconnect()
11:04:31 4456500 start Abort
11:04:41 4466500 end Abort
11:04:41 4466500 end listenerLoop
11:04:41 4466515 start Abort
11:04:41 4466515 start ~Interface()
11:04:41 4466515 start Abort
11:04:41 4466515 start ~Interface()
11:04:41 4466515 end Disconnect()
11:04:41 4466500 end Abort这一步等待了将近 10s
既然确定循环能退出WaitForSingleObject的第二个参数应该设为INFINITE
然后
CreateThread是windows的API不是CRT的函数
CRT中启动线程的函数时_beginthread
用这个操作线程确实比CreateThread安全
主要区别在于异常处理方面
windows核心编程有关于这方面的介绍
有兴趣你可以看看
+1
正确的写法都是必须等待线程自己退出后再closehandle的, 不应该采用10S.
unsigned __stdcall __COMMThread( void* pVoid )
{ CSuperAlarmDeviceUnit* pServer = ( CSuperAlarmDeviceUnit* ) pVoid;
pServer->Run(); SetEvent( pServer->m_ExitEvent ); _endthreadex( 0 ); return 0;}//等待退出
WaitForSingleObject( m_ExitEvent, INFINITE );
线程安全退出自己设个信号量比较简单些,creaatethread会导致内存泄露,但是楼主这样操作是不会的。推荐还是用begin吧。如果你线程体执行时间较长,线程确实会等待比较久。如果实在没办法,考虑在外部杀死线程吧。
如果是我的话会这样设计。void Interface::Abort()
{
m_bLoop = FALSE;
FUNC_START_LOG("Abort");
if (m_hListenerThread)
{
::WaitForSingleObject(m_hListenerThread, INFINITE); //一直等待线程函数返回
FUNC_END_LOG("Abort"); ::CloseHandle(m_hListenerThread);
m_hListenerThread = NULL;
}
}DWORD Interface::_listenerLoop()
{
BYTE report[256];
REPORT decrep; FUNC_START_LOG("listenerLoop");
while (m_bLoop)
{
DWORD dwLen = _readReport(report, sizeof(report), 30000);
if (dwLen > 0) {
memset(&decrep, 0, sizeof(decrep));
if (_decodeReport(&decrep, report, dwLen)) {
if (m_pSignPad) m_pSignPad->onReceive(&decrep);
}
}
else
{
break; //这里跳出循环,结束线程函数
}
}
FUNC_END_LOG("listenerLoop");
return 0;
}