wal-o-mat
wal-o-mat

Reputation: 7344

How to create a process in C++ under Linux?

I'd like to create a process by calling a executable, just as popen would allow. But I don't want to actually communicate through a pipe with it: I want to control it, like sending signals there or find out if the process is running, wait for it to finish after sending SIGINT and so on, just like multiprocessing in Python works. Like this:

pid_t A = create_process('foo');
pid_t B = create_process('bar');

join(B); // wait for B to return
send_signal(A, SIGINT);

What's the proper way to go?

Use case for example:

UPDATE

I see in which direction the answers are going: fork(). Then I'd like to modify my use case: I'd like to create a class which takes a string in the constructor and is specified as follows: When an object is instantiated, a (sub)process is started (and controlled by the instance of the class), when the destructor is called, the process gets the terminate signal and the destructor returns as soon as the process returned.

Use case now: In a boost state chart, start a process when a state is entered, and send termination when the state has been left. I guess, http://www.highscore.de/boost/process/process/tutorials.html#process.tutorials.start_child is the thing that comes closest to what I'm looking for, excpet that it seems outdated.

Isn't that possible in a non-invasive way? Maybe I have a fundamental misunderstanding and there is a better way to do this kind of work, if so I'd be glad to get some hints.

UPDATE 2

Thanks to the answers below, I think I got the idea a little bit. I thought, this example would print "This is main" three times, once for the "parent", and once for each fork() – but that's wrong. So: Thank you for the patient answers!

#include <iostream>
#include <string>

#include <unistd.h>

struct myclass
{
    pid_t the_pid;
    myclass(std::string the_call)
    {
        the_pid = fork();
        if(the_pid == 0)
        {
            execl(the_call.c_str(), NULL);
        }
    }
};

int main( int argc, char** argv )
{
    std::cout << "This is main" << std::endl;
    myclass("trivial_process");
    myclass("trivial_process");
}

Upvotes: 2

Views: 12325

Answers (3)

Sven
Sven

Reputation: 720

Using the previously posted code, try this:

#include <signal.h>
#include <unistd.h>

class MyProc
{
public:
  MyProc( const std::string& cmd)
  {
    m_pid = fork()
    if (pid == 0) {
      execl(cmd.c_str(), cmd.c_str(), NULL);
    }
  }

  ~MyProc()
  {
    // Just for the case, we have 0, we do not want to kill ourself
    if( m_pid > 0 )
    {
      kill(m_pid, SIGKILL);
      wait(m_pid);
    }
  }
private:
  pid_t m_pid;
}

The downside I see on this example will be, you can not be sure, the process has finished (and probably he will not) if the signal is emitted, since the OS will continue after the kill immediately and the other process may get it delayed. To ensure this, you may use ps ... with a grep to the pid, this should work then.

Edit: I have added the wait, which cames up in a comment up there!

Upvotes: 1

user3458
user3458

Reputation:

The below is not a realistic code at all, but it gives you some idea.

pid_t pid = fork()
if (pid == 0) {
  // this is child process
  execl("foo", "foo", NULL);
}
// continue your code in the main process.

Upvotes: 3

Stephane Rouberol
Stephane Rouberol

Reputation: 4384

Have a look to fork() (man 2 fork)

Upvotes: 0

Related Questions