退出前要等待的插槽 [英] Waiting slots to be executed before quitting
问题描述
我有一个读取数据的线程
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屋!