我正在尝试使用QProcess(/ bin / rpm)安装RPM。此QProcess在并发线程中运行,该线程由另一个QThread启动。
QThread retThread = new CMyThread(this);
connect(retThread, SIGNAL(finished()), retThread, SLOT(deleteLater()));
retThread->start();
由于某种原因,QProcess继续运行并且永不退出。当我获得QProcess的pid并使用ps命令检查时,我没有看到正在执行的任何rpm命令。标准输出和标准错误都合并到一个通道并登录到文件。
日志表明rpm命令已完成安装过程。
当我在主线程上使用QProcess运行rpm安装时,看不到相同的行为。这与事件循环有关吗?如果是,如何检查事件循环是否存在。据我所知,线程应该自动从QT 4.4及更高版本创建事件循环。我使用的是QT 4.8
http://qt-project.org/wiki/Threads_Events_QObjects
我觉得事件循环存在,因为我在这个帖子中得到了其他线程排队的信号。
QString ORIGINAL_LOG_FILE = "/var/Component.log";
int PROC_WAIT_TIME= 90000;
QSharedPointer<QProcess> process(new QProcess);
QString program = "/bin/rpm";
QStringList compArgs;
compArgs << "-Uvh"<<"--nodeps"<<"some.rpm";
QStringList configEnvironmentVars = process->systemEnvironment();
process->setEnvironment(configEnvironmentVars);
process->setWorkingDirectory("/tmp/something");
connect(process.data() , SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(slot_finished(int,QProcess::ExitStatus)) );
// process->setWorkingDirectory();
process->setProcessChannelMode(QProcess::MergedChannels);
process->setStandardOutputFile(ORIGINAL_LOG_FILE, QIODevice::ReadWrite | QIODevice::Append | QIODevice::Text);
process->start(program, compArgs);
if (process->waitForStarted())
{
LOGINFO(m_nodeLogFile,QString("Waiting for the process to finish"));
do
{
LOGINFO(m_nodeLogFile, QString("pid = %1").arg((uint)process->pid()));
LOGINFO(m_nodeLogFile , QString("Error = %1").arg(process->error()));
LOGINFO(m_nodeLogFile,QString("Envirnoment variables = %1").arg(configEnvironmentVars.join("\n")));
LOGINFO(m_nodeLogFile,QString("Working directory = %1").arg(process->workingDirectory()));
LOGINFO(m_nodeLogFile,QString("State = %1").arg(process->state()));
}while(!process->waitForFinished(100));
我甚至尝试连接到终点信号。
答案 0 :(得分:1)
要在另一个线程中使用插槽和信号,您需要运行一个事件循环。
在线程的run
方法中,您需要调用exec
。
如果需要,您可以在之前和之后进行设置和拆卸,例如:
void MyThread::run()
{
// Setup code here
exec();
// Tear-down code here
}
要离开事件循环并完成线程,您可以调用线程上的exit
插槽。
QThread::run()
的默认实现只会调用exec
,但如果您重新实施run
,则需要自己致电exec
。
有关详细信息,请查看手册中的Subclassing QThread部分。
答案 1 :(得分:0)
原因是由于我们使用的开源HTTP服务器mongoose。在开源代码中,整个应用程序禁用了SIGCHLD信号。
void signal(SIGCHLD , SIG_IGN);
这用于使整个应用程序不接收子退出信号。 QProcess需要处理此信号以确定子进程是否已退出。