繁体   English   中英

使用select()系统调用语句关闭线程?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM