如何释放线程中创建的QUdpSocket对象

 我来答
huanglenzhi
2015-01-18 · 知道合伙人数码行家
huanglenzhi
知道合伙人数码行家
采纳数:117538 获赞数:517193
长期从事计算机组装,维护,网络组建及管理。对计算机硬件、操作系统安装、典型网络设备具有详细认知。

向TA提问 私信TA
展开全部
  转载很多时候需要在QThread的run中new一个QUdpSocket来收发数据.这时,这个socket对象的释放就成了一个麻烦的问题.

  如果在thread的析构中直接delete这个socket对象,则会出现如下异常:

  QSocketNotifier: socket notifiers cannot be disabled from another thread

  ASSERT failure in QCoreApplication::sendEvent: “Cannot send events to objects owned by a different thread. Current thread 560cb8. Receiver ” (of type ‘QNativeSocketEngine’) was created in thread a617748″, file kernel/qcoreapplication.cpp, line 349
  Invalid parameter passed to C runtime function.
  Invalid parameter passed to C runtime function.

  以下是解决方案:

  1.在线程中定义一个线程释放的标识

  2.在run()中用while来判断这个标识,以便于结束socket对象.

  3.在thread的析构中,设定标识,并使用quit()和wait().

  代码如下:

  UdpSocketThread::UdpSocketThread(QObject *parent) :

  QThread(parent)
  {
  this->socket = 0;
  this->needStop = false;
  }

  UdpSocketThread::~UdpSocketThread()
  {
  this->needStop = true;
  quit();
  wait();
  }

  void UdpSocketThread::run()
  {
  socket = new QUdpSocket;
  connect(socket,SIGNAL(readyRead()),this,SLOT(readPendingDatagrams()));
  socket->bind(2234);
  exec();
  while(this->needStop)
  {
  if(this->socket)
  {
  delete this->socket;
  this->socket = 0;
  }
  break;
  }
  }

  这个线程对象的释放比较有代表性,应该可以解决很多类似的问题.
  另外,方法可能还有其他的,这里只是举了一种而已.
  其实,问题的关键就是:线程中创建的对象就必须在线程中释放.

  PS:

  经shiroki的指正,其实QT有更好的机制来释放对象.那就是deleteLater(). 于是,事情就显得非常简单,请看代码:

  UdpSocketThread::UdpSocketThread(QObject *parent) :

  QThread(parent)
  {
  socket = 0;
  }

  UdpSocketThread::~UdpSocketThread()
  {
  this->socket->deleteLater();
  quit();
  wait();
  }

  void UdpSocketThread::run()
  {
  socket = new QUdpSocket;
  connect(socket,SIGNAL(readyRead()),this,SLOT(readPendingDatagrams()));
  socket->bind(2234);
  exec();

  }
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式