+ -
当前位置:首页 → 问答吧 → 删除类之前,该类的线程还没执行完而出错,要怎么解决?

删除类之前,该类的线程还没执行完而出错,要怎么解决?

时间:2011-12-06

来源:互联网

C/C++ code
/*****
* 接收的线程
*****/
UINT CSerialPort::RevThreadProc(LPVOID pParam)
{
    CSerialPort *pDlg = (CSerialPort*) pParam;
    WaitForSingleObject(Overlapped.hEvent,INFINITE);
        if (pDlg->m_hCom==INVALID_HANDLE_VALUE
            ||!pDlg->m_bRun)//在这里出错,因为CSerialPort已经被删除了
        {
            // ASSERT(0);
            return 0;
        }
}

  typedef pair<int,CSerialPort*> IntUsbcom;
  CSerialPort* m_com=new CSerialPort();
  typedef std::map<int,shared_ptr<CSerialPort>> MyMap;
  MyMap gVcom;
  gVcom.insert(IntUsbcom(1,m_com));


当删除map里的元素CSerialPort时,CSerialPort里的线程RevThreadProc还正在关闭,当判断pDlg->m_hCom就出错了,因为CSerialPort已经被删除了,程序崩溃退出.
要怎么解决?

作者: arabicsara   发布时间: 2011-12-06

等待线程先退出

作者: VisualEleven   发布时间: 2011-12-06

引用 1 楼 visualeleven 的回复:

等待线程先退出

这要怎么判断?
这个类对象里有五六个线程,处理了对每台终端的下载上传文件的处理,因为有几台终端,我就用了map管理;
当一台终端的USB拔掉之后,我就要删除这个map对应的值

作者: arabicsara   发布时间: 2011-12-06

你是判断usb模拟的串口吗?
设置串口的状态,串口会马上结束等待,从而可以达到快速退出线程的目的。

作者: jennyvenus   发布时间: 2011-12-06

引用 2 楼 arabicsara 的回复:
引用 1 楼 visualeleven 的回复:

等待线程先退出

这要怎么判断?
这个类对象里有五六个线程,处理了对每台终端的下载上传文件的处理,因为有几台终端,我就用了map管理;
当一台终端的USB拔掉之后,我就要删除这个map对应的值

线程退出的时候给你的窗口发送一个自定义的消息

作者: VisualEleven   发布时间: 2011-12-06

引用 3 楼 jennyvenus 的回复:

你是判断usb模拟的串口吗?
设置串口的状态,串口会马上结束等待,从而可以达到快速退出线程的目的。
是啊.要怎么设置?
大家都说要等待线程先退出,那要怎么实现?我怎么知道这五六个线程全部结束了?

作者: arabicsara   发布时间: 2011-12-06

用线程句柄waitformultipleobjects

作者: Kevin_qing   发布时间: 2011-12-06

最简单的方法,全局静态变量,类似于智能指针实现机制;有线程在运行就+1,线程退出就-1,当其为0时方可结束

作者: gold_water   发布时间: 2011-12-06

C/C++ code
SetCommMask( g____hComm, EV_RXCHAR | EV_TXEMPTY );


串口线程里面的ReadFile函数立即返回,如果线程里再加一些判断,那么就可以快速退出线程了。

比如

C/C++ code
外面
exitflag = TRUE;
SetCommMask( g____hComm, EV_RXCHAR | EV_TXEMPTY );

线程里面
if( ReadFile( ... ... ) )
{
}
if( exitflag )
{
       return 1;
}

作者: jennyvenus   发布时间: 2011-12-06

C/C++ code
CSerialPort::~CSerialPort()
{
    if (ptRevThreadProc)
    {
        WaitForSingleObject(ptRevThreadProc->m_hThread,INFINITE);//偶尔会在这里出错
    }
    DeleteCriticalSection(&m_bRevCS);
}
现在增加了在删除类之前等待线程退出,偶尔还是会出错,在WaitForSingleObject,不知道为什么这个类已经被删除了
我把智能指针去掉,自己在erase的时候delete,还是会出错
求解决方法:要在哪里等待线程退出?我写在类的析构函数里不行吗?

作者: arabicsara   发布时间: 2011-12-06

引用 8 楼 jennyvenus 的回复:

C/C++ code
SetCommMask( g____hComm, EV_RXCHAR | EV_TXEMPTY );


串口线程里面的ReadFile函数立即返回,如果线程里再加一些判断,那么就可以快速退出线程了。

比如

C/C++ code
外面
exitflag = TRUE;
SetCommMask( g____hComm, EV_RXCHAR | EV_TXE……
我是设置成EV_RXCHAR,有影响吗?我就是在快速退出线程前,在线程里判断的时候出错了(因为类被删除了)

作者: arabicsara   发布时间: 2011-12-06

我觉得你没把问题描述清楚,你想问的东西貌似跟串口啥的没关系,应该是你的控制逻辑上面有问题。

按我的理解,你现在好像是n个对象,由n个不同的线程操作。现在是退出的时候,可能你把还在用的对象删除了,所以出错。


应该是你的对象维护逻辑上面有些问题。假如port需要被2个以上的线程同时关注,那么你在任何一个线程里面删除他都会有问题。唯一的解决办法是用引用计数来自删除。


类似这样

port{
long nRef;
port(){nRef=0;}
void addRef(){interlockedincrcement(&nRef);
long release(){
if(interlockeddecricement(&nRef)==0)
{
  delete this;
  return 0;
}
return nRef;
}
}

port对象自己维护删除自己的时机。

然后需要用到她的线程addRef,不用时release掉。

这样主线程只需等待所有工作线程结束,就可以安全的关闭掉port(release()掉)

作者: Kevin_qing   发布时间: 2011-12-06