在线程内启动QProcess

时间:2015-04-18 13:54:04

标签: c++ multithreading qt qprocess

我一直在努力解决这个基本问题。 我正试图从一个帖子开始QProcess。启动过程工作正常,过程运行正常但我的问题是finished()信号永远不会发出。

以下是我的例子:

我的班级变量是

std::atomic<bool>  recording;
QProcess proc;
std::unique_ptr<std::thread> recordingThread;

班级:

Recorder::Recorder(ParentClass *parent): QObject(parent){

    connect(&proc,SIGNAL(finished(int)),this,SLOT(finishedFFMPEG())); 
}

void Recorder::start(){

    if (!recordingThread){
        recording = true;
        recordingThread.reset(new std::thread(&Recorder::recordThread, this));
    }
}

void Recorder::recordThread(){

    while(recording){
        //writing frame
    }
    proc.start("C:\\ffmpeg.exe", QStringList() <<"-i"<< picDir.c_str() << "-r"<< "30" << "-vcodec"<< "ffv1" << filename.c_str());
    proc.waitForStarted();      
}

void Recorder::stop(){

    if (recordingThread) {
        recording = false;
        recordingThread->join(); recordingThread.reset();  
    }
}

void Recorder::finishedFFMPEG(){
    qDebug() << "finished";
}

start()stop()是从ParentClass中的另一个非GUI线程调用的。

我尝试了一切使用指针,将recordThread()作为QThread运行并在QProcess函数中启动stop(),但我根本就没有收到finished()来自过程的信号。进程本身正在正确执行。我知道问题在于不同的事件循环。

如何在recordThread()完成并抓住QProcess finished()信号后实现启动流程的目标?

1 个答案:

答案 0 :(得分:3)

我不能说我对你的构造不起作用感到非常惊讶。在另一个线程中使用std :: thread执行成员函数recordThread()。到现在为止还挺好。在recordThread()中,你有一个循环,它看起来像是收集/创建/写入帧。一旦循环离开,帧就会通过QProcess传递给ffmpeg。至少这是你的意图。我做对了吗?

现在,在stop()中清除记录标志,这会导致while循环结束。 QProcess开始。但同时你结束了这个QProcess所在的recordThread()线程。并且您期望不仅QProcess能够存活,它可能会存在,而且所有信号/插槽连接都保持不变?

我并不完全知道QProcess会发生什么,可能的比赛,阻塞/非阻挡效果,但我敢打赌你的问题恰好就在这个区域。

还有一件事......我不认为在线程A中创建QProcess是健康的,但是就像你一样在线程B中启动它。

我会尝试这样的事情(未经测试):

while(recording){
 //writing frame
}
QProcess p;
connect(&p,SIGNAL(finished(int)),this,SLOT(finishedFFMPEG()));
p.start(...your ffmpeg stuff...);
p.waitForFinished(-1);

并在finishedFFMPEG()

recordingThread->join(); recordingThread.reset();

当QProcess完成时,线程被杀死。