PDA

View Full Version : QProcess : child process listening parent output ?



Nyphel
15th March 2007, 15:37
Hello,

I know that the QProcess problem has been discussed many times, but there is one thing I can't find on the forum : How the child application can handle the main application's instructons writted on the output channel ?



My main application creates a QProcess linked to "src_2.exe" and listen its output channel :

Veilleur::Veilleur(QWidget *parent) : QObject(parent)
{
myProcess = new QProcess(this);
myProcess->setReadChannelMode(QProcess::MergedChannels);
connect(myProcess, SIGNAL(readyRead()), this, SLOT(SLOT_onReadyReadOut()));

myProcess->start("../../src_2/release/src_2.exe");

myProcess->write("An instruction to perform...");
}

void Veilleur::SLOT_onReadyReadOut()
{
std::cout << "\nReading the child application, on its stdout channel : " << std::endl;
QString message = "";
message.append(myProcess->readAllStandardOutput());
std::cout << "." << message.toStdString() << "." << std::endl;
}



My "src_2" application is the following :

man.cpp :

#include <QApplication>

#include "MailChecker.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

MailChecker * mChecker = new MailChecker();
mChecker->Check();

return app.exec();
}

MailChecker constructor :

MailChecker::MailChecker() : QObject()
{
std::cout << "Message for the parent application : I'm here !" << std::endl;
}



So I would like the child application doing the same job as the parent application.
I would like it to listen the output channel of the parent, in order to give it instructions.
I can't understand how to do it, but I think it would be similar to what i've done for the parent one.

In the parent one it wasn't too difficult, cause I could create my own child application and recognize it every where : she was the "myProcess".
But in the new child application I can't access to the parent one, in order to declare a connect like :
connect(myParentProcess, SIGNAL(readyRead()), this, SLOT(SLOT_onReadyReadOut()));

And how if I could identify the "myParentProcess", where should I declare the connection ?



Thanks for your help :)

high_flyer
15th March 2007, 15:51
connect(myParentProcess, SIGNAL(readyRead()), this, SLOT(SLOT_onReadyReadOut()));

And how if I could identify the "myParentProcess", where should I declare the connection ?

This might be possible, but if it is, it is probably quite exotic.
Why don't you just use sockets?
Or shared memory?
Or Pipes?
Any of these would be better and I think quite simpler to acheave.

Nyphel
15th March 2007, 16:04
I don't know how to use socket with QProcess, and in reality I have created a secnd application in order to hold the QTcpSocket connection cause she takes lots of memory :(.

My main application is a Mail Checker that creates a connection to the server each 5 minutes.
I made a second application that is called each time I want to check the server, with a QTcpSocket.
So I would like no to use Socket to speak with the second application :)

What do you named share memory ? A file for example ?
This was my first idea, but I thought QTcpSocket where made in order to communicate (send and receive) with other process.

And how could I use pipes ?

Thanks for your interest :)

wysota
15th March 2007, 16:12
The parent process can write to the child process' stdin by using QIODevice::write(). Maybe that's enough for your needs?

high_flyer
15th March 2007, 16:26
but I thought QTcpSocket where made in order to communicate (send and receive) with other process.

Correct :)
And you have two processes that need to comunicate - so isn't it a job for a socket?

QTcpSocket connection cause she takes lots of memory
What makes you think that?

Nyphel
18th March 2007, 00:59
Yes, I use the write() function.
But, if I understand well, my child application must loop listening the stdin ?
I can't use signal/slots ?

QTcpSockets : I don't know if it is wanted, but when I connect my sockets to a server it takes 1MO and don'tfree it when I disonnect/close/delete the socket.

wysota
18th March 2007, 01:36
But, if I understand well, my child application must loop listening the stdin ?
The application must just read the input if it wants to. There are no special requirements for that to work.

I can't use signal/slots ?
No, signal-slot connections are not meant for interprocess communication. You can use other IPC mechanisms of course - named or anonymous pipes, message queues, shared memory.


QTcpSockets : I don't know if it is wanted, but when I connect my sockets to a server it takes 1MO and don'tfree it when I disonnect/close/delete the socket.
A socket should take no more than about 100kB to work including the buffer (which resides in kernel space, so it is not counted into resources used by the app). Maybe you have a memory leak somewhere?

Nyphel
20th March 2007, 09:06
QTcpSocket *socket_r;
socket_r = new QTcpSocket();

//socket_r->connectToHost("marathon", 143);

//socket_r->disconnectFromHost();
//socket_r->close();

socket_r->deleteLater();
Here : all the memory has been freed



QTcpSocket *socket_r;
socket_r = new QTcpSocket();

socket_r->connectToHost("marathon", 143); // Takes 1 000 ko

socket_r->disconnectFromHost();
socket_r->close();

socket_r->deleteLater();
Here : 1 000 KO memory has not been freed :(

high_flyer
20th March 2007, 09:15
But how how are you mesuring the memory used by the socket object?
Try this:


QTcpSocket *socket_r;
socket_r = new QTcpSocket();
socket_r->connectToHost("marathon", 143); // Takes 1 000 ko
qDebug()<<"socket size:"<<sizeof(*socket_r);
socket_r->disconnectFromHost();
socket_r->close();
socket_r->deleteLater();


And what is KO?
You mean KB. (KiloByte)

wysota
20th March 2007, 09:48
"sizeof" won't work. You'll only measure the socket object size and not the memory it allocates on the heap (including its private component if it has one).

A better indicator for me would be to instantiate 100 sockets, let them be for a while and then see the memory consumption. Remember that connecting to a host which you pass by a hostname involves also the DNS resolving phase (which uses memory as well). So if your processes resides on the same machine, it would be wiser to pass "127.0.0.1" here instead.

high_flyer
20th March 2007, 09:51
not the memory it allocates on the heap
True - didn"t tink it through.

Nyphel
20th March 2007, 11:29
I mesure it with the Windows task manager.
The server and the client are on different machines.

If I launch multiple connections, it doesn't take more memory (tested with 3 sequentials connections/deconnections). So, I don't think it's a memory leak, instead the 3 connections used the same memory adress... I should try to laucnh the 3 at the same time.



PS : KO for "Kilo Octet"

wysota
20th March 2007, 11:52
The server and the client are on different machines.
Ok, now I'm a bit lost... You want to launch an application on a remote machine using QProcess and listen to its output or are we dealing with two completely separate problems here?

Nyphel
20th March 2007, 12:00
Huhu :)

My main appplication runs on the client machine.
It want's to question the server about new incoming mails.

In order to do that, i have made two small application.
The first, the main, is a GUI based one : trayicon, menus, pop-ups, timers, etc.
The second, the child, is able to communicate with the server.

The main one launch the secnd when must know the number of incoming mails.
The child one answer the main one with the output channel.

I would like the main one to give orders to the child one.
Example : re-check for mails, give me the mails senders, etc.

wysota
20th March 2007, 13:02
So does the "main" one work on the same machine as the "child"?

If so, then I don't see why you can't pass 127.0.0.1 to the socket...

Nyphel
20th March 2007, 13:29
Yes, the two are on the client machine.
I don't want to use Sockets to communicate with the child application, I wanted a signal/slots base communication :)

wysota
20th March 2007, 13:40
You can't have signals/slots - they don't work accross process boundaries! You can either use an stdin/stdout communication (through QProcess) or some kind of proper IPC mechanism like a shared memory, a pipe, message queue, socket or something simmilar.