2013-04-28 7 views
1

Я использую QProcess в первый раз, и, экспериментируя, я заметил, что readyRead сигнализируется до started.QProcess readyRead перед запуском

Я попытался запустить /usr/bin/echo foobar с QProcess и прикреплены две функциями readyRead() и started() сигналов, и я получаю выход в следующем порядке:

  1. процесс начинает с начальным методом() сигналом
  2. dataReady()
  3. начал (сигнал)

Теперь я нахожу немного странным, что started() после dataReady(), потому что обычно процесс переходит в рабочее состояние до, он может фактически создавать данные, но я не могу ничего найти об этом заказе в документации, и, возможно, это совершенно логично, но ... Может кто-нибудь объяснить мне, почему это происходит?

EDIT: Я добавляю код, который ведет себя так, как я уже говорил. Я использую Qt 4.8.4 64 бит.

/*****************************************************************************/ 
// multiproc.hh 
#ifndef MULTIPROC_HH 
#define MULTIPROC_HH 

#include <QObject> 
#include <QtCore> 
#include <iostream> 
#include "node.hh" 

class MultiProc: public QObject { 
    Q_OBJECT 
public: 
    MultiProc(QObject *parent = 0): 
     QObject(parent) { 
     std::cout << "MultiProc\n"; 

     QList<QStringList> args; 
     args << (QStringList() << "/usr/bin/echo" << "Proc 0 running"); 
     args << (QStringList() << "/usr/bin/echo" << "Proc 1 running"); 
     args << (QStringList() << "/usr/bin/cat"); 
     args << (QStringList() << "/usr/bin/cat"); 
     args << (QStringList() << "/usr/bin/tee" << "/etc/hostname"); 

     for (int i = 0; i < args.size(); ++i) 
      _nodes << new Node(this, i, args[i]); 
    } 
signals: 
    void finished(); 
public slots: 
    void run() { 
     std::cout << "Starting all nodes :)\n"; 
     foreach (Node *n, _nodes) 
      n->start(); 
    } 
private: 
    QList<Node *> _nodes; 
}; 

#endif // MULTIPROC_HH 

/*****************************************************************************/ 
// node.hh 
#ifndef NODE_HH 
#define NODE_HH 

#include <QtCore> 
#include <iostream> 

class Node: public QObject { 
    Q_OBJECT 
public: 
    Node(QObject *parent, int id, const QStringList &args): 
     QObject(parent), 
     _id(id), 
     _proc(new QProcess(this)), 
     _args(args) { 
     std::cout << "Node " << _id << " created with command " 
        << args.join(" ").toStdString() << "\n"; 
     connect(_proc, SIGNAL(started()), this, SLOT(started())); 
     connect(_proc, SIGNAL(finished(int)), this, SLOT(finished())); 
     connect(_proc, SIGNAL(readyRead()), this, SLOT(readyRead())); 
     connect(_proc, SIGNAL(error(QProcess::ProcessError)), 
       this, SLOT(error(QProcess::ProcessError))); 
    } 
    void start() { 
     if (_proc->state() == QProcess::NotRunning) { 
      std::cout << "Starting process on node: " << _id << "\n"; 
      _proc->start(_args.at(0), _args.mid(1)); 
     } 
    } 
public slots: 
    void started() { std::cout << "Node " << _id << " started\n"; } 
    void finished() { std::cout << "Node " << _id << " finished\n"; } 
    void readyRead() { std::cout << "Node " << _id << " readyRead\n"; } 
    void error(QProcess::ProcessError err) { 
     std::cout << "Node " << _id << " Error: " << err << "\n"; 
     QCoreApplication::exit(1); 
    } 
private: 
    int _id; 
    QProcess *_proc; 
    QStringList _args; 
}; 

#endif // NODE_HH 

/*****************************************************************************/ 
// main.cpp 
#include <QCoreApplication> 
#include "multiproc.hh" 

int main(int argc, char *argv[]) { 
    QCoreApplication a(argc, argv); 

    MultiProc *p = new MultiProc(&a); 
    QObject::connect(p, SIGNAL(finished()), &a, SLOT(quit())); 
    QTimer::singleShot(0, p, SLOT(run())); 
    return a.exec(); 
} 

А вот кусок выхода:

Node 0 readyRead 
Node 2 started 
Node 0 started 
Node 0 finished 
Node 1 started 
Node 1 readyRead 
Node 4 started 
Node 1 finished 
Node 3 started 
+0

Невозможно воспроизвести, и я не думаю, что это логично. – gatto

+0

Мне тоже не кажется логичным: S Я попытаюсь изолировать его как можно скорее и посмотреть, является ли это проблемой Qt или что. – AkiRoss

ответ

2

я могу воспроизвести это с Linux и Qt 5.0.1 на первый запуск процесса, а затем подключения сигналов:

process.start("echo foo", QIODevice::ReadWrite); 

connect(&process, SIGNAL(started()), this, SLOT(started())); 
connect(&process, SIGNAL(readyReadStandardOutput()), this, SLOT(readyRead())); 

Однако, если я сначала подключу сигналы, а затем запустил процесс, слот started() называется первым как исключенный.

Эта функция, которую вы нашли, может считаться ошибкой, и вы можете сообщить об этом в Qt bug tracker.

Edit:

Я был в состоянии воспроизвести проблему с вашим кодом. Я также смог исправить это, сделав небольшое изменение функции start() Node. После вызова start() вызовите waitForStarted() перед продолжением. Обратите внимание, что, ожидая, только когда состояние процесса равно QProcess::Starting, вы избегаете проблем, если пытаетесь запустить несуществующую программу. В этом случае процесс никогда не начнется. Конечно, этого также можно избежать, используя другой тайм-аут, чем -1 для функции waitForStarted.

void start() 
{ 
    if (_proc->state() == QProcess::NotRunning) 
    { 
     std::cout << "Starting process on node: " << _id << "\n"; 
     _proc->start(_args.at(0), _args.mid(1)); 
     if (_proc->state() == QProcess::Starting) 
      _proc->waitForStarted(-1); 
    } 
} 
+0

Я запускаю процесс после подключения. – AkiRoss

+0

Не могли бы вы показать свой код? И какую версию Qt вы используете? – 2013-04-29 18:33:59

+0

Конечно, я отправляю его прямо сейчас. Извините за задержку. – AkiRoss

Смежные вопросы