Reputation: 7344
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
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
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