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

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

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

4

2 回答 2

3

scanf被子进程终止时捕获的 SIGCHLD 信号中断。在这种情况下EOF也返回。

QProcessstuff 确实为 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;
}
于 2009-11-11T00:01:10.023 回答
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;
于 2009-11-11T15:18:30.663 回答