4

I have two C++ programs built in Ubuntu, and I want to run them concurrently. I do not want to combine them into one C++ project and run each on a different thread, as this is causing me all sorts of problems.

The solution I effectively want to emulate, is when I open two tabs in the terminal, and run each program in a separate tab. However, I also want one program (let's call this Program A) to be able to quit and rerun the other program (Program B). This cannot be achieved just in the terminal.

So what I want to do is to write some C++ code in Program A, which can run and quit Program B at any point. Both programs must run concurrently, so that Program A doesn't have to wait until Program B returns before continuing on with Program A.

Any ideas? Thanks!

Karnivaurus
  • 22,823
  • 57
  • 147
  • 247

3 Answers3

4

In Linux you can fork the current process, which creates a new process. Then you have to launch the new process with some exec system call.

Refer to: http://man7.org/linux/man-pages/man2/execve.2.html

For example:

#include <unistd.h> /* for fork */
#include <sys/types.h> /* for pid_t */
#include <sys/wait.h> /* for wait */

int main(int argc,char** argv)
{
    pid_t pid=fork();
    if (pid==0)
    {
      execv("/bin/echo",argv);
    }
}
dau_sama
  • 4,247
  • 2
  • 23
  • 30
3

Take a look at the Linux operating system calls, fork() and exec(). The fork() call will create two copies of the current process which continue to execute simultaneously.

  • In the parent process, fork()'s return value is the PID (process ID) of the child process.
  • In the child process, fork()'s return value is 0.
  • On error, fork()'s return value is -1.

You can use this to your advantage to control the behavior of the parent and child. As an example:

#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>

int main(int argc,char** argv)
{
    char* progB = "/bin/progB";
    char* args[progName, "arg1", "arg2", ..., NULL];
    char* env[NULL]; // can fill in environment here.

    pid_t pid=fork();
    if (pid==0)
    {
        // In child...
        execv(progB, args, env);
    }
    else if (pid == -1) 
    {
        // handle error...
    } 
    else 
    {
        // In parent; pid is the child process.
        // can wait for child or kill child here.
    }
}

To wait until your child exits (in the third case above), you can use wait(2), which returns your child pid on successful termination or -1 on error:

pid_t result = waitpid(pid, &status, options);

To kill your child preemptively, you can send a kill signal as described in kill(2):

int result = kill(pid, SIGKILL); // or whatever signal you wish

This should allow you to manage your processes as described in the original question.

rholmes
  • 4,064
  • 3
  • 25
  • 34
3

You have multiple options here:

  1. The traditional POSIX fork / exec (there are literally tons of examples on how to do this in SO, for example this one).
  2. If you can use Boost then Boost process is an option.
  3. If you can use Qt then QProcess is an option.

Boost and Qt also provide nice means manipulating the standard input/output of the child process if this is important. If not the classical POSIX means should do fine.

Community
  • 1
  • 1
Rudolfs Bundulis
  • 11,636
  • 6
  • 33
  • 71