退出前要等待的插槽 [英] Waiting slots to be executed before quitting

查看:74
本文介绍了退出前要等待的插槽的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个读取数据的线程

I've a thread that read datas

class MyThread: QThread
{
  ...
}

void MyThread::run ()
{
  uint8_t* buffer; // in my real code, it's a ring, so there is not read during write
  // ...

  while (true)
  {
    if (isInterruptionRequested())
      return;
    USB_READ(buffer);
    emit newData(buffer);
  }
}

在我的UI类中,我有:

In my UI Class I have:

connect(this, &UIClass::newData, m_thread, &MyThread::newData);

// ...

void newData(uint8_t* data)
{
  // Process data
}

void UIClass::closeEvent(QCloseEvent *event)
{
   disconnect(this, &UIClass::newData, m_thread, &MyThread::newData);
   m_thread->requestInterruption();
   m_thread->wait();
}

如果当我单击关闭"时,线程被破坏导致指针data无效,则存在问题.有时会调用信号newData,该信号导致我的函数使用无效的指针和segfault.如何确保不会发生这种情况?

The problem with that if, when I click on "close", the thread is destroyed that cause the pointer data to be invalid. The signal newData is sometimes called that cause my function to work with invalid pointer and segfault. How to be sure that is not gonna happend ?

现在,我使用std :: this_thread :: sleep_for()任意延迟,它可以工作,但我觉得这不是很漂亮

For now, I use a std::this_thread::sleep_for() with an arbitrary delay, it works, but I not find this very beautiful

我的想法是:
-断开信号
-等待待处理信号被执行
-退出

That I have in my mind :
- disconnect the signal
- wait for the pendings signals to be executed
- exit

推荐答案

问题是您从一个线程向另一个线程发送了一个指针,而没有确保该指针保持有效.

The problem is that you send a pointer from one thread to another without ensuring the pointer stays valid.

您有多种选择来解决此问题.使用QSharedPointer(或stl中的类似实用程序)来保存数据,这样做可以确保您的指针保持有效(或者如果您还使用QWeakPointer,则可以为您提供一种检测指针何时变为无效的方法).或者,您可以使用QByteArray传递数据,但这将创建一个副本.

You have multiple choices to solve this. Either use QSharedPointer (or similar utilities from the stl) to hold your data, doing so will ensure your pointer will remain valid (or provide you a way to detect when the pointer becomes invalid if you also use QWeakPointer). Or you could make use of QByteArray to pass the data, but this will make a copy.

示例1

void MyThread::run ()
{
  QSharedPointer<uint8_t> buffer (new uint8_t[N]()); // Do not delete[], QSharedPointer will handle it
  ...

  emit newData(buffer);

}
void newData(QSharedPointer<uint8_t> data)
{
  // data is always valid
  // Process data
}

示例2

void MyThread::run ()
{
  QSharedPointer<uint8_t> buffer (new uint8_t[N]());
  ...

  emit newData(buffer);

}
void newData(QWeakPointer<uint8_t> data)
{
  // data might not be valid but we can check
  QSharedPointer<uint8_t> buffer (data);
  if (!buffer)
      return;
  // Process data
}

示例3

void MyThread::run ()
{
  uint8_t[N] buffer;
  ...

  emit newData(QByteArray(buffer, size));

}
void newData(QByteArray data)
{
  // data is valid
  // Process data
}

这篇关于退出前要等待的插槽的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆