在线程内启动 QProcess
Starting QProcess inside a thread
我已经为这个基本问题苦苦挣扎了一段时间。
我正在尝试从线程启动 QProcess
。启动进程工作正常并且进程运行正常,但我的问题是 finished()
信号从未发出。
这是我的例子:
我的 class 变量是
std::atomic<bool> recording;
QProcess proc;
std::unique_ptr<std::thread> recordingThread;
class:
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
到在 stop()
函数中启动 QProcess
,但我从来没有从进程接收 finished()
信号。该过程本身正在正确执行。我知道问题在于不同的事件循环。
如何实现在 recordThread()
完成并捕获 QProcess
finished()
信号后启动进程的目标?
我不能说我对您的构造不起作用感到非常惊讶。您在另一个线程中使用 std::thread 执行成员函数 recordThread()。到目前为止,一切都很好。在 recordThread() 中,您有一个循环,看起来像 collects/creates/writes 帧。一旦循环结束,帧就会通过 QProcess 传递给 ffmpeg。至少这是你的意图。我做对了吗?
现在,在 stop() 中清除记录标志,这会导致 while 循环结束。 QProcess 启动。但与此同时,您结束了这个 QProcess 所在的 recordThread() 线程。而且您希望不仅 QProcess 存活下来(它可能会存活下来),而且所有 signal/slot 连接都保持完好无损?
我不完全知道 QProcess 会发生什么,可能的竞争,blocking/non-blocking 影响,但我敢打赌你的问题就出在这方面。
还有一件事...我认为在线程 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);
并在完成的 FFMPEG()
recordingThread->join(); recordingThread.reset();
然后线程在 QProcess 完成时被杀死。
我已经为这个基本问题苦苦挣扎了一段时间。
我正在尝试从线程启动 QProcess
。启动进程工作正常并且进程运行正常,但我的问题是 finished()
信号从未发出。
这是我的例子:
我的 class 变量是
std::atomic<bool> recording;
QProcess proc;
std::unique_ptr<std::thread> recordingThread;
class:
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
.
我尝试了所有方法,从使用指针,运行 我的 recordThread()
作为 QThread
到在 stop()
函数中启动 QProcess
,但我从来没有从进程接收 finished()
信号。该过程本身正在正确执行。我知道问题在于不同的事件循环。
如何实现在 recordThread()
完成并捕获 QProcess
finished()
信号后启动进程的目标?
我不能说我对您的构造不起作用感到非常惊讶。您在另一个线程中使用 std::thread 执行成员函数 recordThread()。到目前为止,一切都很好。在 recordThread() 中,您有一个循环,看起来像 collects/creates/writes 帧。一旦循环结束,帧就会通过 QProcess 传递给 ffmpeg。至少这是你的意图。我做对了吗?
现在,在 stop() 中清除记录标志,这会导致 while 循环结束。 QProcess 启动。但与此同时,您结束了这个 QProcess 所在的 recordThread() 线程。而且您希望不仅 QProcess 存活下来(它可能会存活下来),而且所有 signal/slot 连接都保持完好无损?
我不完全知道 QProcess 会发生什么,可能的竞争,blocking/non-blocking 影响,但我敢打赌你的问题就出在这方面。
还有一件事...我认为在线程 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);
并在完成的 FFMPEG()
recordingThread->join(); recordingThread.reset();
然后线程在 QProcess 完成时被杀死。