asynchronous c++ inter-process control - c++

I'm writing this with c++ on Ubuntu 12.04 LTS and i am explicitly not using any BOOST libraries.
What I want to do is have a parent process and two or more children run simultaneously.
The parent process acts like an event listener and task dispatcher. The children handle the tasks the parents tells them to; these tasks are system calls, and the parent doesn't care when they finish.
What I have done successfully so far is
parent will fork() some children and retain their pids
children are suspended (S) immediately after being fork() with pause()
parent resumes (R) and detects events in a standard event loop way
what I need to know next is how to resume a child and return to the parent while child is still running.
So my questions are, can a parent and child run simultaneously and safely in this manner? (where the parent doesn't care what the child is doing after its resumed)
What do I have to do to in general to resume a child process after a pause()?
below is the constructor function that forks the children
childManager(int number_of_children, pid_t parent) {
int i=0;
while(number_of_children--) {
if(parent == getpid())
{
this->parent = parent;
children.push_back({++i,_IDLE,fork()});
if(parent != getpid()) pause();
}
}
}

The only question I see here is
What do I have to do to in general to resume a child process after a pause()?
Send it a signal whose action is either to execute a signal-catching function or terminate the process. For example:
kill(children[i], SIGUSR);
That said, this is a less than ideal way to do this. You could just as easily have the children block on a pipe waiting for the parent to tell them to do something. Or about 30 similar things which don't involve signals.

To answer your specific questions:
So my questions are, can a parent and child run simultaneously and safely in this manner? (where the parent doesn't care what the child is doing after its resumed)
The parent process will have to call wait or waitpid to harvest the child processes after they exit. If you do not do that you will be left with zombie processes. You can do this in a nonblocking way inside your event loop in the parent process.
What do I have to do to in general to resume a child process after a pause()?
You have to send a signal to the child process. You do this by calling kill in the parent process. You will need to install a signal handler in the child process to catch the signal - use sigaction for that.

Related

How to keep track of which all child processes are killed in c++

I am writing a server. It uses fork() to create new child processes. I want to kill the child processes when a parent process dies. I am planning to use an array to store the pids of the child processes.But there is chance that the child process might terminate before the parent process. In this case if we call kill function using SIGKILL and pid of the child process that already terminated, will it throw an exception?
When a child process terminates, a SIGCHLD signal is sent to the parent. You can handle this signal in the parent to check what child has terminated on it's own, before you got a chance to wait for it. And you should wait() for all children to avoid zombie processes.
You can also take a look at this thread for an alternative way to have the children terminate when the parent terminats: How to make child process die after parent exits?

How do I synchronize two processes in C++ (Windows)?

Parent process launches a child process by invoking CreateProcess() method which returns immediately even before the child process is initialized. How do I make the parent process wait until the Child process got initialized and started executing? WaitForSingleObject() call makes the parent process to wait until the child thread terminates or until timeout.
Is there any similar method which makes the parent process to wait until the child process is intialized?
You can create a named event in WinAPI in the parent process and set it to unsignalled state. Call WaitForSingleObject on the event handle. Then in the child process you can open event by name and signal it (call SetEvent()) after the child process is initialized.
If you are using threads, one of the simpliest way to make parent thread wait until the child finishes is using .join() function. In the parent process's end use
child.join();

Notification to a parent process

When using the fork system call, I have seen that many a times that the parent calls waitpid so that the child can finish.
My question here is does the child send a notification to the parent preocess. Without using any shared resource, how can a parent identify that the chils has been completed?
The OS sends a SIGCHLD to the parent when the child exits. You can choose to poll waitpid() using WNOHANG, or to just check with wait() after receiving a SIGCHLD. The child process doesn't need to do anything in particular, this is all managed by the OS.
In Linux Operating system, every child is having some parent and even if the parent dies before the child, the child is inherited by init(PID:1) process. This thing is done so that there should not any zombie process(process entry is there in the process table but process is actually already died) which is taking memory space for no use.
The kernel keeps an eye on all the processes which are died either due to their complete execution or due to some other reason(like invalid memory access) and retains some information like child's exit status. When the child terminates a SIGCHLD signal is sent to the parent. By default the signal is simply ignored. However commonly wait() system call implemented in a handler for the SIGCHLD, so that the parent may act upon the exit status of the child.
In addition to receiving SIGCHLD as mentioned by Erik, you can poll the child for events of interest by using WNOHANG. Here's an example:
pid_t pid = fork();
if (pid) {
while (1) {
int status;
int waitpid(pid, &status, WNOHANG);
if (pid == waitpid && WIFEXITED(status))
break;
// do other stuff
}
}

send SIGINT to child process

I am trying to create a child process and then send SIGINT to the child without terminating the parent. I tried this:
pid=fork();
if (!pid)
{
setpgrp();
cout<<"waiting...\n";
while(1);
}
else
{
cout<<"parent";
wait(NULL);
}
but when I hit C-c both process were terminated
Don't use CTRL-C, this sends a signal to all processes with the same controlling terminal (ie, in the same session). That's something that setpgid doesn't change though I think there's a setsid (set session ID) call for that purpose.
The easiest solution is simply to target the specific process rather than a session. From the command line:
kill -INT pid
From C:
kill (pid, SIGINT);
where pid is the process ID you want to send the signal to.
The parent can get the relevant PID from the return value from fork(). If a child wants its own PID, it can call getpid().
Aha, the mystery of process groups and sessions and process group leaders and session group leaders appears again.
Your control/C sent the signal to a group. You need to signal an individual pid, so follow paxdiablo's instructions or signal ("kill") the child from the parent. And don't busy wait! Put a sleep(1) in the loop, or better yet, one of the wait(2) system calls.
You could try implementing a SIGINT signal handler which, if a child process is running, kills the child process (and if not, shuts down the application).
Alternatively, set the parent's SIGINT handler to SIG_IGN and the child's to SIG_DFL.

Are child processes created with fork() automatically killed when the parent is killed?

I'm creating child processes with fork() in C/C++.
When the parent process ends (or is killed for some reason) I want all child processes to be killed as well.
Is that done automatically by the system? Or I have to do it myself?
Pre-existing similar questions:
How can I cause a child process to exit when the parent does?
How to make child process die after parent exits?
No. If the parent is killed, children become children of the init process (that has the process id 1 and is launched as the first user process by the kernel).
The init process checks periodically for new children, and waits for them (thus freeing resources that are allocated by their return value).
The question was already discussed with quality answers here:
How to make child process die after parent exits?