程序关闭时提示错误,估计时线程释放没做好,请问怎么解决?

zhou_cj 2003-12-12 11:35:48
程序运行时没问题,关闭时出现错误
错误信息:
“DvrWin.exe产生了错误,会被windows关闭,您需要重新启动程序
正在创建错误日志”

我在程序中第一了一个keyproc线程类,用来侦听和处理串口操作的:
类的声明:
class keyproc : public TThread
{


程序中的声明:
class keyproc *PannelThread = NULL;
定义:
PannelThread = new keyproc(false);
释放
if(PannelThread)
{
//PannelThread->Terminate();
delete PannelThread;
}
如果加上PannelThread->Terminate();会出现访问0x0000000地址错误
我不知道怎么去解决,请高手指点。谢谢!!
...全文
25 点赞 收藏 20
写回复
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
1cctv 2003-12-21
你让线程序结束(不是强行终止),通过线程循环里的控制,线程可以自己结束.
但不是你让线程序结束,它就立该能结束的,用WaitFor,等到它结束.
回复
zhou_cj 2003-12-19
PannelThread->Terminate()只是把Terminated置为true
估计是delete PannelThread会导致CloseHandle(m_ov.hEvent) 得不到执行,但这会导致程序不正常退出吗?
在delete PannelThread之前加上PannelThread->WaitFor()就行?但是我不明白WaitFor什么时候返回?是不是Execute()结束后WaitFor就会返回?
回复
1cctv 2003-12-18
我的感觉是这样: 线程99%的时间是阻塞在WaitCommEvent上,
如果PannelThread->Terminate()了,则WaitCommEvent后面的
代码一定是得不到执行的,然后线程序对象被Delete了,由于
串口我不太熟,我不知到线程被删掉后,WaitCommEvent还能不
能返回,以及返回到那里?

如果要求线程退出,可在线程之外使WaitCommEvent返回,比如
关串口或是CloseHandle(m_ov.hEvent)(你比我清楚),然后方
法就多了,判断一下是正常返回还是要退出线程.

设立线程退出标志,使WaitCommEvent返回,主线程PannelThread->Waitfor()就可以了.
回复
zhou_cj 2003-12-17
线程循环代码如下:
void keyproc::loop(void)
{
unsigned char echo;
unsigned char cmd;
int retv, timeout = time(NULL);
OVERLAPPED m_ov;
DWORD dwEvent = 0;
int Readed;
DWORD dwLength;
COMSTAT ComStat ;
DWORD dwErrorFlags;
DWORD dwError;
BOOL fReadStat ;
bool WaitEventResult;
int i = 0;
memset(&m_ov, 0, sizeof( OVERLAPPED )) ;
m_ov.hEvent = CreateEvent( NULL,TRUE,FALSE,NULL );
while (!Terminated)
{

setCurrentTime();
if(net == 1)
{
echoSingleLed(21);
net = 0;
}
if(save == 1)
{
echoSingleLed(22);
save = 0;
}
if(warn == 1)
{
echoSingleLed(23);
warn = 0;
}
for(i = 0;i <= 15;i++)
{
if(ch[i] == 1)
echoSingleLed(i);
}
WaitEventResult = WaitCommEvent(m_hComm,&dwEvent,&m_ov);
if (GetLastError() == ERROR_IO_PENDING)
{
WaitEventResult = (WaitForSingleObject(m_ov.hEvent,INFINITE)==WAIT_OBJECT_0);
}
if (WaitEventResult)
{
//one char come
ClearCommError( m_hComm, &dwErrorFlags, &ComStat ) ;
Readed = receive(&echo,1);
ResetEvent(m_ov.hEvent) ;
if(Readed == 1)
{
if (inputKey(echo) == 0)
{
timeout = time(NULL);
}
}
cmd = 0x40;
sendWithEcho(&cmd, 1);

//Thread_Status_Message("loop");
}


}
CloseHandle(m_ov.hEvent) ;
PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
}
而且如果这里没有字符到来,过了超时时间(设的是10秒),WaitCommEvent 会正常返回,但是WaitForSingleObject也会立即返回,根据我的理解,好象如果没有字符到来,WaitForSingleObject应该会一直等待。这又是什么回事呢?
回复
tiger8098 2003-12-16
试试在Terminate()以后使用Waitfor();,如果程序停在Waitfor(),那么就是你的线程对Terminate()没有进行处理
回复
yjy1001 2003-12-16
线程是楼主自己写的吧。

看看线程是否有 char 的new事件。

例如:

char ch = new[128]; //.....1
char ch = new(128); //.....2

等类似的语句。
如果是 1类型,看后面是否用
delete []ch;
来释放,不是 ,那么你的线程出错原因是内存泄露。
如果是 2类型,看是否使用了 ch[1] = 0; ch[2] = 2; 等
如果用了,那么就是没有为 ch申请内存而试图使用导致出错。
修改为 char ch = new[128];申请内存 delete []ch; 释放

当然 不一定是 char[]类型的错。
只是偶写串口程序出过跟你类似的错误而已!
回复
ljlln 2003-12-16
为什么不让线程自动释放?
在线程的构造函数里加上:
FreeOnTerminate=true;
回复
1cctv 2003-12-16
是把线程循环中的代码贴出来看看.
不是把终止线程序的代码贴出来看看.

回复
1cctv 2003-12-15
问题在于: Terminate()是强制中止的,线程的清理代码是得不到执行的.

线程的退出,最好还是由线程自己决定,有多种方法,查看退出标志,PeekMessage等等.

线程循环中要有一些控制的.
把你的线程循环代码贴出来看看.
回复
OperDone 2003-12-15
应该不是线程的原因吧
回复
hswu 2003-12-15
这样做不是一个好程序员应该做的,建议还是找到未释放的资源,除非你有你的理由。
回复
pzoon 2003-12-15
if(PannelThread)
{
//PannelThread->Terminate();
delete PannelThread;
PannelThread=NULL;
}
回复
vargent77 2003-12-15
同意上面意见,可能有资源没释放,还可能是你lock了什么东西,所以最后忘了
回复
zhou_cj 2003-12-14
是不是有东西没有释放完?
或者释放的时候读写了非法内存?
回复
sprewellkobe 2003-12-13
来电的方法是不错,。但没解决为什么有错误的根本问题

顶一下
回复
goldpony 2003-12-13
up
回复
constantine 2003-12-13
回复
constantine 2003-12-12
没有见过,为什么你会认为是线程的问题呢?
回复
netsys2 2003-12-12
if( PannelThread != NULL )
{
try {
PannelThread->Terminate();
}
__except (TRUE) {// Ignore any exception when we are closing
}
}
delete PannelThread;
PannelThread = NULL;
}
回复
熬夜程序猴 2003-12-12
类似的问题我也在我的软件中遇到过,我的方法是在工作线程结束后,向住线程发送消息
回复
发动态
发帖子
Windows SDK/API
创建于2007-08-02

1202

社区成员

C++ Builder Windows SDK/API
申请成为版主
社区公告
暂无公告