Question

I need a way to launch executable (process) from secondary thread. The wxWidgets toolkit I use give me no way to the best of my knowledge and now I have to seek platform dependent way (Linux and Windows only) way to do that.

The executable will read and write to the file. Other than knowing that the process is still running or not (and if possible exit code) there is no much this thread is going to do with process itself. After process terminate, the thread will read the written file, analyze it and send result to GUI thread for displaying. I have no idea how to do it since I have been depending on wxExecute all the times.

Was it helpful?

Solution 2

You will have to move quite a few parts of your code from the secondary thread to the main thread. The wxWidgets documentation you refer to says it all:

When a wxProcess object is passed to wxExecute(), its OnTerminate() virtual method is called when the process terminates. This allows the program to be (asynchronously) notified about the process termination and also retrieve its exit status which is unavailable from wxExecute() in the case of asynchronous execution.

And below:

Currently wxExecute() can only be used from the main thread, calling this function from another thread will result in an assert failure in debug build and won't work.

So, you need to eliminate the need to call wxExecute from the secondary thread. How exactly you should do this depends on your application, but it will probably involve the secondary thread sending a custom wxWidgets event to the main thread using wxQueueEvent. The main thread then handles the event by calling wxExecute in asynchronous mode and retrieving its result later on.

Now what to do with the result?

Ideally, you rework your application logic such that the secondary thread does not need the result but instead:

  1. the main thread handles it all by itself, -or-
  2. another secondary thread is started and handles it.

This will minimize the amount of synchronization you have to do, and thus reduce the probability of hard-to-find concurrency programming errors.

OTHER TIPS

Do you really want separate processes, or will threads do.

To get separate processes, you need fork() for Linux and CreateProcess() for Windows. The best approach is often to make a function to encapsulate it.

bool RunProces(const std::string &sCmdLine)
{
    #if defined(WIN32)
        // launch with CreateProcess() ...
    #else
        // launch with fork() ...
    #endif
    return bSuccess;
}

If, however, you can just use threads, you can use the portable std::thread class.

An alternative approach is to use popen() (_popen() for Windows). This launches a new process and redirects its output (stdout) to a pipe. You can then read the pipe to retrieve the sub-process output.

A couple of notes about popen():

  1. Redirecting the standard output makes it impractical for the sub-process to interact with the user.
  2. There would be some overhead setting up the pipe. Probably not important unless you are spawning large numbers of sub-processes.
  3. I've never seen popen() used to launch a non-console Windows program (with no main() function). I wouldn't be surprised if there are problems doing that.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top