7
votes

Processus enfant STDIN ne reçoit pas de données, envoyé par le processus parent

Processus parent chaîne d'écriture "Message \ n" code> au processus d'enfant STDIN. Mais le processus enfant ne le reçoit pas. Où est le problème dans le code?

Qt 4.7.3 P>

Code de processus parent: P>

// class TestChild : public QMainWindow
void TestChild::TestChild()
    // QFile TestChild::input;
    connect( &input, SIGNAL( readyRead() ),
        this, SLOT( readInput() ) );
    input.open( 0, QIODevice::ReadOnly ); // stdin
}

void TestChild::readInput()
{
    QString line;
    line.append( '(' );
    line.append( QString::number( input.bytesAvailable() ) )
    line.append( ')' );
    line.append( input.readAll() );

    list.append( line ); // add line to QListView
}


2 commentaires

Testchild est-il un QProcess? Et l'entrée est un QioDevice, pas une sous-classe?


@Chris: Non, TestChatd - Objet de la fenêtre principale du processus d'enfant. Dans le processus parent, nous créons un enfant à l'aide de ChildProcess objet. Mon erreur: entrée est qfile, merci.


3 Réponses :


0
votes

Ce que je crois avoir besoin de faire est de lire à partir de l'objet QProcess actuel (dans ce cas, si je comprends correctement).

Notez que Qprocess est en réalité une sous-classe de QioDevice, et prend également une note particulière de la Fonctions suivantes: P>

QProcess::setReadChannel()
QProcess::readAllStandardOutput()


1 commentaires

Non. ChildProcess est un objet de contrôle dans le processus parent. Utilisation de ChildProcess Processus d'objet Imprimer la chaîne d'impression sur STDIN ( TESTPARENT :: WRITETOTECHILDPROCESSOUPUT () ). Et le processus enfant doit lire cette chaîne de stdin . Donc, dans le processus enfant lisyyread () Signal de entrée qfile doit être émis (mais il n'y a pas de lectureyread () Signal émis, TestChild :: ReadInput () Slot n'est pas appelé).



1
votes

La documentation indique que qfile n'émet pas jamais le signal lectureyread () .

Mais il y a une classe privée: qwineventanifier dans src / corelib / kernel / qwinevennotifier_p.h (link) qui pourrait fonctionner avec getStdhandle (std_input_handle) .

Une autre alternative consiste à attendre l'entrée avec une boucle de blocage à l'intérieur d'un fil dédié: xxx

Vous pouvez également regarder d'autres méthodes RPC (par exemple, Qlocalsocket , qsharedmemory ).


6 commentaires

Merci, va essayer qwineventivement. Mais le problème existe toujours: j'ai toujours démarré une minuterie que chaque x ms écrit au journal de fichier entrée.bytesAvailable () , et il écrit toujours 0 . Est bytesAvailable () utilisation ici aussi?


QsharedMemorory n'a pas essayé. Mais sur qlocalsocket , qlocaleerver (tuyau nommé dans Windows): je dois toujours échanger des noms de tuyaux (1 pour chaque qlocalserver ). Y a-t-il une autre méthode simple pour envoyer un nom de tuyau, autre que stdin / stdout?


1. Vous ne pouvez pas jeter un coup d'œil sur Stdin Buffer avec des bibliothèques standard C / C ++. Ce ne serait donc pas une surprise si Qt ne le permet pas non plus. 2. Vous pouvez envoyer le nom du tuyau comme des arguments de sous-processus.


Et que dois-je utiliser pour la communication des enfants-> parents? Toujours utiliser stdout?


"Vous pouvez ensuite écrire à l'entrée standard du processus en appelant écrire () et lisez la sortie standard en appelant lecture (), readline () et getchar ()." ( doc.qt.nokia.com/latest/qprocess.html )


Oui, vous pouvez utiliser stdout mais qlocalsocket peut être bidirectionnel afin de ne pas avoir mélanger les deux méthodes de communication. Le problème n'est pas que vous ne pouvez pas utiliser de lecture / écriture avec l'entrée / sortie standard du processus enfant, mais celle-ci () sur le côté du processus d'enfant, ne fonctionne pas pour STDIN. Vous devriez utiliser l'API native (par exemple ici ) sinon vous devez utiliser un Blocing lire l'appel.



7
votes

Il n'y a aucun moyen de connecter de manière portante dans la boucle d'événement QT pour les événements STDIN / STDOUT. Les travaux suivants sur des plates-formes non-Windows: xxx pré>

"0" est le descripteur de fichier (stdin). P>

Je voudrais utiliser ce qui précède, puis simuler quelque chose de similaire sur Windows à travers un filetage de blocage qui lit de STDIN et génère un signal: p> xxx pré>

puis, dans le processus enfant: p>

StdinThread *t = new StdinThread(this);
connect(t, SIGNAL(incomingData(QByteArray)), this, SLOT(processInputData(QByteArray)));
connect(t, SIGNAL(finished()), this, SLOT(brokenInputChannel()));
t->run();


2 commentaires

+1. C'est utile, merci. Vous ne savez pas si qprocess :: écrire (sdin piping) fonctionne sous Windows? À d'autres termes: puis-je écrire à STDIN de l'enfant?


Oui, vous pouvez. Windows prend en charge la tuyauterie. Faites attention à la mise en mémoire tampon.