Qthread deleteLater()崩溃程序

时间:2018-01-12 02:03:24

标签: c++ qt segmentation-fault qthread qeventloop

QT 4.8:我的代码中出现了许多段错误和I / O可能的错误,我无法弄清楚。从印刷语句中我看到了许多奇怪和不一致的行为,可能表明竞争条件。很多时候一切都很完美。有时我在调用worker析构函数后立即出现I / O错误,表明主连接deleteLater()问题。其他时候,如果我尝试在析构函数中删除audioOutput,它会工作很多次,然后在析构函数中间随机给我一个段错误(或I / O)。我相信我的问题可以归结为两件事,工作者清理/连接quit()/ deletelater()调用以及我在worker中的递归循环,它需要每次创建自己的事件循环,因此可能在之前的调用之前发出完成的信号清理干净?

具体来说,我的问题是:

什么可能导致deleteLater()创建I / O可能的错误?

我应该如何删除worker类中的指针,以便在正确的时间(结束)删除它们?或者QT会为我处理这个吗?

Gui和.h

QByteArray qbyte;
int numOfPlays;
int numOfPlaysRun;
bool quit = false;
QBuffer *qbuff;
QAudioFormat format;
QAudioOutput *audioOutput;

PlayAudio::PlayAudio(QByteArray *qbyte_, int num)
{
    qbyte=*qbyte_;
    numOfPlays=num;
    qbuff=new QBuffer();
    qbuff->setData(qbyte);
    qbuff->open(QIODevice::ReadOnly); 
       //set format
    audioOutput  = new QAudioOutput(format,this);  
    connect(audioOutput,SIGNAL(stateChanged(QAudio::State)),
                           SLOT(finishedPlaying(QAudio::State)));
}

void PlayAudio::::play()
{
    if (!quit)
    {
        audioOutput->start(qbuff);
        QEventLoop loop;
        do {
            loop.exec();            
        } while(!quit);
    }
}

 void PlayAudio::finishedPlaying(QAudio::State state)
{
    if (state == QAudio::IdleState)
    {
        if (numOfPlaysRun< numOfPlays && !quit)
        {
            numOfPlaysRun++;
            play();
        }
        else
        {
            //should i ever stop loop myself? or is that done from main?
            //quit=true;
            emit finished();
        }
    }
}
PlayAudio:: ~PlayAudio()
{
    // still have  qbuff and audioOutput to delete. If i do here i sometimes            
    //get segment faults or IO error.
}

工人阶级和.h

connect(audioWorker, SIGNAL(finished()), audioWorker,SLOT(deleteLater()));

更新

仍然存在间歇性问题但是注释掉以下行有助于在设置quit = true时结合其中一些。

Observable.merge

但是这可能会导致内存泄漏?

更新2:

我开始认为我在这里和自己说话,但我想我明白了。这似乎是一个计时问题,因为线程在工作人员实际完成之前返回finished(),因为有时间从quit()信号退出,一旦工作人员发出finish(),就会关闭开放循环。所以我现在从每个循环关闭的工作者发出一个自定义信号并在main中跟踪它。一旦我收到我期望的东西,然后释放wait()并删除线程然后工作者。不确定这是否正确但似乎有效。对我来说似乎很讨厌,但IMO线程不应该在工作人员完成之前完成,这似乎毫无意义。但是哦。好吧。

0 个答案:

没有答案