为什么这个程序失败(有时)?

时间:2009-11-10 21:57:22

标签: c++ qt process stdin

#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命令行执行。

为什么这个程序有时打印失败,有时会保持循环?

修改 这不是关于scan / printf的问题。 同样的问题是如果我使用iostreams + string。这个问题是关于QProcess与父进程的文件描述符的交互。

2 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分: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;