2009-11-10 3 views
2
#include <cstdio> 
#include <QtCore/QProcess> 

int main (int argc, char** argv) { 
    // if we remove 3 following lines, the problem described below doesn't exists!! 
    QProcess process; 
    process.start ("asdqwe"); // doesn't matter what we try to execute here. 
    process.waitForStarted (1000); 

    while (true) { 
    char buf[100]; 
    if (scanf ("%s", buf) == EOF) { // it looks like stdin is closed! 
     printf("FAIL\n"); 
     return 1; 
    } 
    printf ("%s\n", buf); 
    } 
    return 0; 
} 

이 코드는 문제를 보여주는 단순한 코드입니다. 전체 응용 프로그램에서 프로세스와의 읽기/쓰기 통신이 필요합니다.왜이 프로그램이 실패합니까 (때로는)?

나는 그것을 컴파일 :

g++ -o out ./main.cpp -I /usr/include/qt4/ -lQtCore 

터미널에서 bash는 명령 줄에서 실행합니다.

이 프로그램이 때때로 FAIL을 인쇄하고 때로는 루프 상태를 유지하는 이유는 무엇입니까?

편집 : 이것은 scan/printf에 대한 질문이 아닙니다. 동일한 문제는 iostreams + string을 사용하는 경우입니다. 이 질문은 QProcess와 상위 프로세스의 파일 설명 자의 상호 작용에 관한 것입니다.

+0

모두 사용했다 코드가 표시됩니다. 가져 가서 컴파일하고 실행하십시오. –

+0

... 그리고 당신은 이상한 행동을 보게 될 것입니다 (적어도 리눅스에서는) –

+0

include에 실수가있었습니다. 결정된. –

답변

3

scanf은 자식 프로세스가 종료되었을 때 걸린 SIGCHLD 신호에 의해 중단되었습니다. 이 경우 EOF도 반환됩니다.

QProcess 물건이 (소스를 확인) SIGCHLD에 대한 신호 처리기 설정합니까 : 정말 스트림을 사용 (현재 4.5.3)

Q_GLOBAL_STATIC(QProcessManager, processManager) 

QProcessManager::QProcessManager() 
{ 
#if defined (QPROCESS_DEBUG) 
    qDebug() << "QProcessManager::QProcessManager()"; 
#endif 
    // initialize the dead child pipe and make it non-blocking. 
    // (pipe and fcntl skipped - P. Shved.) 

    // set up the SIGCHLD handler, which writes a single byte to the dead 
    // child pipe every time a child dies. 
    struct sigaction oldAction; 
    struct sigaction action; 
    memset(&action, 0, sizeof(action)); 
    action.sa_handler = qt_sa_sigchld_handler; 
    action.sa_flags = SA_NOCLDSTOP; 
    ::sigaction(SIGCHLD, &action, &oldAction); 
    if (oldAction.sa_handler != qt_sa_sigchld_handler) 
     qt_sa_old_sigchld_handler = oldAction.sa_handler; 
} 
+0

아, 그건 그럴듯 해 보입니다. Pavel에게 감사드립니다. 그런데 어떻게해야합니까? 실제 EOF와 SIGCHLD의 차이점은 무엇입니까? 어떻게 크로스 플랫폼을 만들 수 있습니까? –

+0

'errno == EINTR'을 검사해야합니다. 리눅스에서 작동; Windows에서 같은 변수가 있지만, 어떻게 그 플랫폼에서 작동하는지 모르겠습니다. 아니면 그냥'cin >> s'을 사용하십시오. –

+0

cin >> s는 똑같은 문제가 있습니다. –

0
#include <cstdio> 
#include <QtCore/QProcess> 

int main (int argc, char** argv) { 
    // if we remove 3 following lines, the problem described below doesn't exists!! 
    QProcess process; 
    process.start ("asdqwe"); // doesn't matter what we try to execute here. 
    process.waitForStarted (1000); 

    while (true) { 
    char buf[100]; 
    if (scanf ("%s", buf) == EOF) { // it looks like stdin is closed! 
     if (errno == EINTR) { 
     errno = 0; 
     continue; 
     } 
     printf("FAIL\n"); 
     return 1; 
    } 
    printf ("%s\n", buf); 
    } 
    return 0; 
} 

, 나는

cin.clear(); 
errno = 0; 
관련 문제