[英]Closing a thread with select() system call statement?
我有一个使用select系统调用监视串行端口的线程,该线程的运行功能如下:
void <ProtocolClass>::run()
{
int fd = mPort->GetFileDescriptor();
fd_set readfs;
int maxfd=fd+1;
int res;
struct timeval Timeout;
Timeout.tv_usec=0;
Timeout.tv_sec=3;
//BYTE ack_message_frame[ACKNOWLEDGE_FRAME_SIZE];
while(true)
{
usleep(10);
FD_ZERO(&readfs);
FD_SET(fd,&readfs);
res=select(maxfd,&readfs,NULL,NULL,NULL);
if(res<0)
perror("\nselect failed");
else if( res==0)
puts("TIMEOUT");
else if(FD_ISSET(fd,&readfs))
{//IF INPUT RECEIVED
qDebug("************RECEIVED DATA****************");
FlushBuf();
qDebug("\nReading data into a read buffer");
int bytes_read=mPort->ReadPort(mBuf,1000);
mFrameReceived=false;
for(int i=0;i<bytes_read;i++)
{
qDebug("%x",mBuf[i]);
}
//if complete frame has been received, write the acknowledge message frame to the port.
if(bytes_read>0)
{
qDebug("\nAbout to Process Received bytes");
ProcessReceivedBytes(mBuf,bytes_read);
qDebug("\n Processed Received bytes");
if(mFrameReceived)
{
int no_bytes=mPort->WritePort(mAcknowledgeMessage,ACKNOWLEDGE_FRAME_SIZE);
}//if frame received
}//if bytes read > 0
} //if input received
}//end while
}
问题是当我从该线程退出时,使用
delete <protocolclass>::instance();
该程序因malloc内存损坏的glibc错误而崩溃。 在使用gdb检查核心时,发现在退出线程时它正在处理数据,从而导致错误。 协议类的析构函数如下所示:
<ProtocolClass>::~<ProtocolClass>()
{
delete [] mpTrackInfo; //delete data
wait();
mPort->ClosePort();
s_instance = NULL; //static instance of singleton
delete mPort;
}
这是由于选择吗? 涉及select时,销毁对象的语义是否发生变化? 有人可以提出一种干净的方法来销毁涉及select调用的线程。
谢谢
我不确定您使用的是哪种线程库,但是您可能应该以一种或另一种方式向线程发出信号,指出该线程应该退出而不是杀死它。
最简单的方法是在线程退出时保留设置为true的布尔值,并在select()调用上使用超时来定期检查它。
ProtocolClass::StopThread ()
{
kill_me = true;
// Wait for thread to die
Join();
}
ProtocolClass::run ()
{
struct timeval tv;
...
while (!kill_me) {
...
tv.tv_sec = 1;
tv.tv_usec = 0;
res = select (maxfd, &readfds, NULL, NULL, &tv);
if (res < 0) {
// Handle error
}
else if (res != 0) {
...
}
}
您还可以设置管道并将其包含在readfds中,然后从另一个线程向其中写入一些内容。 这样可以避免每秒唤醒并立即中断线程。
另外,您当然不应该使用没有某种锁的布尔型变量,...
删除后,线程是否还在查看mpTrackInfo?
看不到代码很难。
但我认为析构函数应该做的第一件事是等待任何线程死亡(最好使用某种形式的join()以确保它们都被考虑在内)。 一旦它们死了,您就可以开始清理数据。
您的线程不仅仅是具有某些成员的内存,因此仅删除并依靠析构函数是不够的。 由于我不了解qt线程,因此我认为此链接可以助您一臂之力 : trolltech消息
两个可能的问题:
mpTrackInfo
? 您在等待线程退出之前将其删除。 线程是否在某个地方使用了此数据,甚至在删除之后? run()
的循环似乎永远运行,这将导致析构函数中的wait()
永远等待。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.