Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从Qthread调用时QProcess未退出_Qt_Qthread_Qprocess - Fatal编程技术网

从Qthread调用时QProcess未退出

从Qthread调用时QProcess未退出,qt,qthread,qprocess,Qt,Qthread,Qprocess,我正在尝试使用QProcess(/bin/RPM)安装RPM。此QProcess正在由另一个QThread启动的并发线程中运行 QThread retThread = new CMyThread(this); connect(retThread, SIGNAL(finished()), retThread, SLOT(deleteLater())); retThread->start(); 由于某些原因,QProcess会继续运行,并且永远不会退

我正在尝试使用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安装时,没有看到相同的行为。这与事件循环有关吗。如果是,如何检查事件循环是否存在。据我所知,一个线程应该自动创建Qt4.4及以上版本的事件循环。我正在使用Qt4.8

我觉得事件循环是存在的,因为我在这个线程中得到了其他线程排队信号

   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));
QString原始日志文件=“/var/Component.LOG”;
int PROC_WAIT_TIME=90000;
QSharedPointer进程(新的QProcess);
QString程序=“/bin/rpm”;
QStringList比较;
compArgs setProcessChannelMode(QProcess::MergedChannels);
进程->设置标准输出文件(原始日志文件,QIODevice::ReadWrite | QIODevice::Append | QIODevice::Text);
过程->启动(程序、比较);
如果(进程->waitForStarted())
{
LOGINFO(m_nodeLogFile,QString(“等待流程完成”);
做
{
LOGINFO(m_nodeLogFile,QString(“pid=%1”).arg((uint)进程->pid());
LOGINFO(m_nodeLogFile,QString(“错误=%1”).arg(进程->错误());
LOGINFO(m_nodeLogFile,QString(“环境变量=%1”).arg(configEnvironmentVars.join(“\n”));
LOGINFO(m_nodeLogFile,QString(“工作目录=%1”).arg(进程->工作目录());
LOGINFO(m_nodeLogFile,QString(“State=%1”).arg(进程->状态());
}而(!process->waitForFinished(100));

我甚至尝试连接到完成信号。

要在另一个线程中使用插槽和信号,需要运行事件循环

在线程的
run
方法中,需要调用

如果需要,您可以在安装之前和之后进行安装和拆卸,例如:

void MyThread::run()
{
  // Setup code here
  exec();
  // Tear-down code here
}
要离开事件循环并完成线程,可以调用线程上的
exit

QThread::run()
的默认实现将只调用
exec
,但如果重新实现
run
,则需要自己调用
exec


有关更多信息,请参阅手册中的部分。

要在另一个线程中使用插槽和信号,需要运行事件循环

在线程的
run
方法中,需要调用

如果需要,您可以在安装之前和之后进行安装和拆卸,例如:

void MyThread::run()
{
  // Setup code here
  exec();
  // Tear-down code here
}
要离开事件循环并完成线程,可以调用线程上的
exit

QThread::run()
的默认实现将只调用
exec
,但如果重新实现
run
,则需要自己调用
exec


有关更多信息,请参阅手册中的部分。

原因是我们使用的开源HTTP服务器mongoose。在开源代码中,整个应用程序禁用了SIGCHLD信号

 void signal(SIGCHLD , SIG_IGN);

这会导致整个应用程序未收到子进程退出信号。QProcess需要处理此信号以确定子进程是否已退出。

原因是我们使用的开源HTTP服务器mongoose。在开源代码中,整个应用程序禁用了SIGCHLD信号

 void signal(SIGCHLD , SIG_IGN);
这会导致整个应用程序不接收子进程退出信号。QProcess需要处理此信号以确定子进程是否已退出