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 + 文字列を使用する場合です。この質問は、QProcess と親プロセスのファイル記述子との相互作用に関するものです。

4

2 に答える 2

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;
}
于 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 に答える