PDA

View Full Version : receive signal from a thread of an external program



bigbill
30th November 2010, 16:48
Hello, I am using QProcess class in order to start an external program.

QProcess gzip2;
gzip2.start("/home/hurricane/console-4.o");
if (!gzip2.waitForStarted())
return false;
gzip2.write("somethink!\n");

I want the Qt program to freeze in that point until a signal from the external program (console-4.o) is received.
Is that possible with the usage of threads or shall I use another method?

For instance, a thread of the external program send that signal

pthread_cond_signal( &condition_cond );

How I can receive it from the Qt program?

I will appriciete any help

Vasilis

bothorsen
1st December 2010, 15:12
You can't do that. QProcess starts a different application, so the threads in the two are not in any way connected.

You might be able to use inter process signals. Otherwise you have to look at some form of IPC.

MattPhillips
1st December 2010, 21:41
Hi Vasilis,

There are at least three ways to do this, 2 of which are pretty straightforward.

1) Use QProcess::stateChanged ( QProcess::ProcessState newState ). It's a signal; just connect it to a slot in your main application. When the process is running the signal will be emitted with newState==QProcess::Running. I've never used this but it looks like it's designed to give you exactly what you want.

2) Have console4.o send its standard output or standard error to your main process, use signals QProcess::readyReadStandardOutput/QProcess:readyReadStandardError to get this.

3) This is probably more than you need, but for continuous ongoing IPC you can set up a local socket connection (QLocalSocket/QLocalServer) between the two processes and read/write ad libidum.

HTH,
Matt

wysota
1st December 2010, 21:59
Hi Vasilis,

There are at least three ways to do this, 2 of which are pretty straightforward.

1) Use QProcess::stateChanged ( QProcess::ProcessState newState ). It's a signal; just connect it to a slot in your main application. When the process is running the signal will be emitted with newState==QProcess::Running. I've never used this but it looks like it's designed to give you exactly what you want.

2) Have console4.o send its standard output or standard error to your main process, use signals QProcess::readyReadStandardOutput/QProcess:readyReadStandardError to get this.

3) This is probably more than you need, but for continuous ongoing IPC you can set up a local socket connection (QLocalSocket/QLocalServer) between the two processes and read/write ad libidum.


Matt,

I don't see how any of what you write here would make the main application "freeze" and wait until it is signalled from the child process.

The OP obviously wants something that works like a wait condition.

@bigbill - you can use QSystemSemaphore. You can also redesign your main application so that it doesn't have to actively wait for the other application but can continue its work where it left off upon some QProcess signal. None of the two situations require the use of threads.

If you want to wait until the other process quits, then also consider using the system() call instead of QProcess.

MattPhillips
1st December 2010, 22:31
wysota, you're right--none of those will stop the execution flow. So if the OP really needs to 'freeze' things then they won't work. But I would have thought the natural way to set up what the OP is doing would be to have the start() call be the last line in the method and then return control to the main loop, waiting for an appropriate signal. All visible gui's can be setEnable(false)'ed if need be.

But of course if the main app is really frozen, it won't be able to process any events at all, will it? So

4) Use a QTimer to periodically check the state of the child process after it has been started. Then immediately enter an infinite loop which continuously checks a volatile variable flag. When the timer slot finds that the process is running, flip the variable flag and break out of the loop, continuing execution. YUCK, but this will freeze things up pretty good.

I looked at QSystemSemaphore. At the time the main app would try to acquire a resource, the child app will likely not even be running yet. Hence there will be an available resource, the main app will take it, and execution will continue in the main app. As I'm seeing it anyway--how would you do this?

Matt

wysota
1st December 2010, 22:41
wysota, you're right--none of those will stop the execution flow. So if the OP really needs to 'freeze' things then they won't work. But I would have thought the natural way to set up what the OP is doing would be to have the start() call be the last line in the method and then return control to the main loop, waiting for an appropriate signal. All visible gui's can be setEnable(false)'ed if need be.
Assuming there is a ui involved... All the code we've seen supports a claim that if he just ends the method at this point, nothing will happen as the QProcess object will go out of scope.


4) Use a QTimer to periodically check the state of the child process after it has been started.
That's a really bad idea.


I looked at QSystemSemaphore. At the time the main app would try to acquire a resource, the child app will likely not even be running yet. Hence there will be an available resource, the main app will take it, and execution will continue in the main app. As I'm seeing it anyway--how would you do this?
Wrong. You can (and in fact have to) initalize the semaphore to 0 and also acquire the semaphore only after the child process is already scheduled by the OS to be started (it does not have to be actually started yet). Then the order of events doesn't matter - the parent will only be able to continue after the child releases the semaphore.