2013-05-03 53 views
0

QProcess (/ bin/rpm)를 사용하여 RPM을 설치하려고합니다. 이 QProcess는 다른 QThread에 의해 시작된 동시 스레드에서 실행 중입니다.Qthread에서 호출 할 때 QProcess가 종료되지 않습니다.

 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

이유는 우리가 사용하고있는 오픈 소스 HTTP 서버 몽구스 때문입니다. 오픈 소스 코드에서 전체 애플리케이션에 대해 SIGCHLD 신호가 비활성화되었습니다.

void signal(SIGCHLD , SIG_IGN); 

전체 응용 프로그램이 하위 종료 신호를 수신하지 못하게하는 데 사용됩니다. QProcess는 하위 프로세스가 종료되었는지 판별하기 위해이 신호를 처리해야합니다.

0

다른 스레드에서 슬롯과 신호를 사용하려면 실행중인 이벤트 루프가 필요합니다.

스레드의 run 메서드 내에서 exec으로 전화해야합니다.

당신은 설정하고 눈물 다운 이전을 할 수 있으며, 필요한 경우, 예를 들어 후 :

void MyThread::run() 
{ 
    // Setup code here 
    exec(); 
    // Tear-down code here 
} 

이벤트 루프를 떠나 스레드를 완료하려면, 당신은 스레드에서 exit 슬롯을 호출 할 수 있습니다.

QThread::run()의 기본 구현은 exec을 호출하지만 run을 다시 구현하면 exec에 직접 전화해야합니다.

자세한 내용은 설명서의 Subclassing QThread 섹션을 참조하십시오.