parent process and child process timing - c++

Hi I have a simple question, however the timing issue is troubling me. Assume this is the code.
#include <stdio.h>
int main() {
int p = fork();
if (p==0) {
printf("ok\n");
sleep(1);
} else {
printf("hey!");
sleep(1);
}
printf("done!");
return 0;
}
My question is, will "done!" always be executed twice when the sleep is 1sec for both parent and child. Because I notice that when I increase the sleep to 10 seconds in the child process (p==0 case), I only see "done!" once.

I think when you increase sleep time parent process exited faster and stdout file descriptor closed. note that child and parent process shared their file descriptors.
if you want you can use _exit() in your parent process so when it exited, child process file descriptors will not be closed. in this way after 10 sec you see "done!" in your terminal. for use of this method you must use printf("done!\n") to flush your buffer manually because _exit() did not flush your buffer.
If you want you can use something like wait() in your parent process to issue wait on your child process.

Related

Let threads execute untill a specific point, wait for the rest to get there, execute the remaining code sequentially

I have some code that needs to benchmark multiple algorithms. But before they can be benchmarked they need to get prepared. I would like to do this preparation multi-threaded, but the benchmarking needs to be sequential. Normally I would make threads for the preparation, wait for them to finish with join and let the benchmarking be done in the main thread. However the preparation and benchmarking are done in a seperate process after a fork because sometimes the preparation and the benchmarking may take too long. (So there is also a timer process made by a fork which kills the other process after x seconds.) And the preparation and benchmarking have to be done in the same process otherwise the benchmarking does not work. So I was wondering if I make a thread for every algorithm if there is a way to let them run concurrently until a certain point, then let them all wait untill the others reach that point and then let them do the rest of the work sequentially.
Here is the code that would be executed in a thread:
void prepareAndBenchmark(algorithm) {
//The timer thread that stops the worker after x seconds
pid_t timeout_pid = fork();
if (timeout_pid == 0) {
sleep(x);
_exit(0);
}
//The actual work
pid_t worker_pid = fork();
if (worker_pid == 0) {
//Concurrently:
prepare(algorithm)
//Concurrently up until this point
//At this point all the threads should run sequentially one after the other:
double result = benchmark(algorithm)
exit(0);
}
int status;
pid_t exited_pid = wait(&status);
if (exited_pid == worker_pid) {
kill(timeout_pid, SIGKILL);
if(status == 0) {
//I would use pipes to get the result of the benchmark.
} else {
//Something went wrong
}
} else {
//It took too long.
kill(worker_pid, SIGKILL);
}
wait(NULL);
}
I have also read that forking in threads migth give problems, would it be a problem in this code?
I think I could use mutex to have only one thread benchmarking at a time, but I don't want to have a thread benchmarking while others are still preparing.

fork() system call within a daemon using _exit()

There are lot of questions on fork() but I am little bit confused in this code.I am analyzing a code in c++ in that I have got this function.
int daemon(int nochdir, int noclose)
{
switch (fork())
{
case 0: break;
case -1: return -1;
default: _exit(0); /* exit the original process */
}
if (setsid() < 0) /* shoudn't fail */
return -1;
/* dyke out this switch if you want to acquire a control tty in */
/* the future -- not normally advisable for daemons */
printf("Starting %s [ OK ]\n",AGENT_NAME);
switch (fork())
{
case 0: break;
case -1: return -1;
default: _exit(0);
}
if (!nochdir)
{
chdir("/");
}
if (!noclose)
{
dup(0);
dup(1);
}
return 0;
}
So the fork will create an exact copy of the code from where the fork() has been called. so,
Is switch executed twice or once?
If twice then in the switch what if the child executes first? Will it just break or go to the other statements?
What If the parent executes? will the main process be terminated and child will continue?
Edit:
So the switch will also run twice once with parent and once with child. and behaves on the return values.
And the final thing is, the daemon is a predefined function and it has been redefined and used like user created daemon. How it will create the daemon process and what the
`if (!nochdir)
{
chdir("/");
}`
and
if (!noclose)
{
dup(0);
dup(1);
}
I am calling this function like this.
if (daemon(0, 0) < 0)
{
printf("Starting %s [ Failed ]\n",AGENT_NAME);
exit(2);
}
Is switch executed twice or once?
It is said that fork is the function that is called once but returns twice, that is once in each process: once in parent and once in a child.
man :
On success, the PID of the child process is returned in the parent,
and 0 is returned in the child. On failure, -1 is returned in the
parent, no child process is created, and errno is set appropriately
It might return just once (-1): only in parent if child wasn't created. It always returns in the parent ( -1 on error, > 0 on success).
If twice then in the switch what if the child executes first? Will it
just break or go to the other statements?
It is unknown whether child or parent returns first. After fork() all the memory segments are copied into child, but it continues with the correct value 0 returned from the fork(). Parent continues with pid of the child. You use return value of fork in the code to determine whether you are child or parent. Maybe this will get more clear if you write code this way
int daemon( int nochdir, int noclose)
{
pid_t pid; /* to drive logic in the code */
if ( ( pid = Fork()) < 0) /* fork and remember actual value returned to pid */
return -1;
if( pid > 0)
_exit(0); /* exit the original process */
// here pid is 0, i.e. the child
What If the parent executes? will the main process be terminated and
child will continue?
What if the parent exit() is called before any child instructions? Then yes, parent will terminate, child will do on its own. Both the parent and the child processes possess the same code segments, but execute independently of each other (unless you added some synchronization).
http://linux.die.net/man/2/fork
Yes, when the parent executes it will continue in the default: case as the switch will have returned the child process id.
The common convention of saying that fork() is a function which is called once and returns two times is a bit obfuscating as it only returns once in each process space. The question is whether a child was created or not which determines which of the two ways a parent returns. The parent never gets a result of '0' from fork(), only either -1 or >0. The child always (if at all) gets zero.
If the child wasn't created, then fork() never returns in its process space.
Unless there's an error, fork will return twice: once in the parent process and once in the child process. fork creates a copy of the current process, then continues execution in both processes and you can determine by the return value. Note that the copy (child) is not a "perfect" copy: for example, in the child, all threads are terminated except for the one executing fork. The exact behavior is a bit complex.
It's not specified whether the parent or child process continues execution first. This depends on your OS and might even be totally random on your OS. Since they are two separate processes (which happen to run the same code) the order doesn't matter. The parent process will get a return value >0 (or -1 on error) and thus execute the default: label. The child process will get a return value of 0 and thus execute the case 0: label. This return value of fork is how the parent process knows it's a parent and the child process that it is a child (the child can query its own PID using getpid(2) and the PID of its parent using getppid(2)).
Yes, the parent runs into the default: label and executes _exit, thus terminating. The child will continue to run (note that here setsid() is very important; without it, the child would not continue to run if the shell session of your parent exits). This is the usual pattern for creating a daemon: when you run the program, it spawns actual main program (the daemon) through forking and then exits. For example, in the shell, you'll see the program exits quickly, but when you enter ps you can see that there's a process with the same name (your daemon).

Forking, Signals and how they interact with global variables in C

I am trying to understand how fork()/Linux Kernel deals with global variables.
Given code:
#include<signal.h>
#include<unistd.h>
#include<stdio.h>
#include<errno.h>
#include <sys/types.h>
pid_t pid;
int counter = 2;
void handler1(int sig)
{
counter = counter - 1;
printf("%d", counter);
exit(0);
}
int main()
{
signal(SIGUSR1, handler1); //Install Handler
printf("%d", counter); //Print Parent global variable
pid = fork( ); //Fork(), child pid = 0, parent's pid = positive int.
if (pid == 0) //Parent skips this, child goes into infinite loop
{
while(1) {}; // simulate doing some work
}
kill(pid, SIGUSR1); //While child is the loop, parents calls to terminate the child.
//Child will stop the infinite loop, and will not proceed any
//Will it call handler1 ???
wait(NULL); //Wait for child to be ripped
//Will it call handler1 second time ???
counter = counter + 1; //This will surely increment global variable
printf("%d", counter);
exit(0);
}
The output is 2123
How does Unix/Linux kernel deals with global variables after fork() and signal handlers are called ??? Do they get shared between child & parent ?
Another issues I have with this code, is how kill() & wait() will deal with global variables and what set will they use - parent's or child's ?? And will they call signal handler ???
Thanks !
The child gets an independent copy of the global variables. The two copies are not shared.
After fork(), the entire process, including all global variables, is duplicated. The child is an exact replica of the parent, except that it has a different PID, a different parent, and fork() returned 0.
A signal handler in the child will use the child's independent copy of the global variable.
The reason you're seeing 2 printed twice is that you haven't flushed standard output after printing it. This is what happens:
counter is equal to 2.
Parent process executes printf("%d", counter);, which puts "2" into the stdout output buffer, but does not flush it. No output appears yet.
fork() is called, which duplicates the process. There are now two copies of the counter variable, and both are set to 2. There are also two instances of the stdout output buffer, both of which contain the string "2". No output appears yet.
The parent sends SIGUSR1 to the child, and blocks on wait().
The child executes handler1(), which decrements the child's copy of counter to 1, and puts "1" into the child's stdout output buffer (which now contains "21").
The child executes exit(0), which as a side-effect flushes stdout. The output "21" appears now, written by the child, and the child exits.
wait() returns in the parent process. The parent increments its copy of counter to 3, and then prints "3" into its stdout output buffer (which now contains "23").
The parent executes exit(0), which as a side-effect flushes stdout. The output "23" appears now, and the parent exits.
If you put fflush(stdout); before the fork(), the 2 will only be printed once, and the output will be "213". It is good practice to flush all buffered output streams before calling fork().
fork creates a copy of the process in its current state. Nothing is shared except explicitly-mapped shared memory resources (anonymous shared maps, shared file maps, sysv shared memory blocks, and POSIX shared memory blocks).
You should also be aware that while the new process has its own copy of the file descriptor table, these file descriptors refer to the same "open file descriptions" in the kernel. They share a current seek position, among other things.
For further details, see:
http://www.opengroup.org/onlinepubs/9699919799/functions/fork.html

C++ fork() and execv() problems

I am kind of newbie on C++, and working on a simple program on Linux which is supposed to invoke another program in the same directory and get the output of the invoked program without showing output of the invoked program on console. This is the code snippet that I am working on:
pid_t pid;
cout<<"General sentance:"<<endl<<sentence<<endl;
cout<<"==============================="<<endl;
//int i=system("./Satzoo");
if(pid=fork()<0)
cout<<"Process could not be created..."<<endl;
else
{
cout<<pid<<endl;
execv("./Satzoo",NULL);
}
cout<<"General sentance:"<<endl<<sentence<<endl;
cout<<"==============================="<<endl;
One of the problem I encounter is that I am able to print the first two lines on console but I cant print the last two lines. I think the program stops working when I invoke the Satzoo program.
Another thing is that this code invokes Satzoo program twice, I dont know why? I can see the output on screen twice. On the other hand if I use system() instead of execv(), then the Satzoo works only once.
I haven't figured out how to read the output of Satzoo in my program.
Any help is appreciated.
Thanks
You aren't distinguisng between the child and the parent process after the call to fork(). So both the child and the parent run execv() and thus their respective process images are replaced.
You want something more like:
pid_t pid;
printf("before fork\n");
if((pid = fork()) < 0)
{
printf("an error occurred while forking\n");
}
else if(pid == 0)
{
/* this is the child */
printf("the child's pid is: %d\n", getpid());
execv("./Satzoo",NULL);
printf("if this line is printed then execv failed\n");
}
else
{
/* this is the parent */
printf("parent continues execution\n");
}
The fork() function clones the current process and returns different values in each process. In the "parent" process, it returns the pid of the child. In the child process, it returns zero. So you would normally invoke it using a model like this:
if (fork() > 0) {
cout << "in parent" << endl;
} else {
cout << "in child" << endl;
exit(0);
}
I have omitted error handling in the above.
In your example, both of the above code paths (both parent and child) fall into the else clause of your call to fork(), causing both of them to execv("./Satzoo"). That is why your program runs twice, and why you never reach the statements beyond that.
Instead of using fork() and doing everything manually (properly managing process execution is a fair amount of work), you may be interested in using the popen() function instead:
FILE *in = popen("./Satzoo", "r");
// use "in" like a normal stdio FILE to read the output of Satzoo
pclose(in);
From the fork() manpage:
RETURN VALUE
Upon successful completion, fork() shall return 0 to the child process and shall return the process ID of the child process to the parent process. Both processes shall continue to execute from the fork() function. Otherwise, -1 shall be returned to the parent process, no child process shall be created, and errno shall be set to indicate the error.
You check to make sure it succeeds, but not whether the pid indicates we're in the child or the parent. Thus, both the child and the parent do the same thing twice, which means that your program gets executed twice and the ending text is never printed. You need to check the return value of fork() more than just once.
exec - The exec() family of functions replaces the current process image with a new process image.
system - Blocks on execution of the command. Execution of the calling program continues after the system command returns
There are three return value tests you want with fork
0: you are the child
-1: error
other: you are the parent
You ran the other program from both the child and the parent...

How do I write a program that tells when my other program ends? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
How do I write a program that tells when my other program ends?
The only way to do a waitpid() or waitid() on a program that isn't spawned by yourself is to become its parent by ptrace'ing it.
Here is an example of how to use ptrace on a posix operating system to temporarily become another processes parent, and then wait until that program exits. As a side effect you can also get the exit code, and the signal that caused that program to exit.:
#include <sys/ptrace.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char** argv) {
int pid = atoi(argv[1]);
int status;
siginfo_t si;
switch (ptrace(PTRACE_ATTACH, pid, NULL)) {
case 0:
break;
case -ESRCH:
case -EPERM:
return 0;
default:
fprintf(stderr, "Failed to attach child\n");
return 1;
}
if (pid != wait(&status)) {
fprintf(stderr, "wrong wait signal\n");
return 1;
}
if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) {
/* The pid might not be running */
if (!kill(pid, 0)) {
fprintf(stderr, "SIGSTOP didn't stop child\n");
return 1;
} else {
return 0;
}
}
if (ptrace(PTRACE_CONT, pid, 0, 0)) {
fprintf(stderr, "Failed to restart child\n");
return 1;
}
while (1) {
if (waitid(P_PID, pid, &si, WSTOPPED | WEXITED)) {
// an error occurred.
if (errno == ECHILD)
return 0;
return 1;
}
errno = 0;
if (si.si_code & (CLD_STOPPED | CLD_TRAPPED)) {
/* If the child gets stopped, we have to PTRACE_CONT it
* this will happen when the child has a child that exits.
**/
if (ptrace(PTRACE_CONT, pid, 1, si.si_status)) {
if (errno == ENOSYS) {
/* Wow, we're stuffed. Stop and return */
return 0;
}
}
continue;
}
if (si.si_code & (CLD_EXITED | CLD_KILLED | CLD_DUMPED)) {
return si.si_status;
}
// Fall through to exiting.
return 1;
}
}
On Windows, a technique I've used is to create a global named object (such as a mutex with CreateMutex), and then have the monitoring program open that same named mutex and wait for it (with WaitForSingleObject). As soon as the first program exits, the second program obtains the mutex and knows that the first program exited.
On Unix, a usual way to solve this is to have the first program write its pid (getpid()) to a file. A second program can monitor this pid (using kill(pid, 0)) to see whether the first program is gone yet. This method is subject to race conditions and there are undoubtedly better ways to solve it.
If you want to spawn another process, and then do nothing while it runs, then most higher-level languages already have built-ins for doing this. In Perl, for example, there's both system and backticks for running processes and waiting for them to finish, and modules such as IPC::System::Simple for making it easier to figure how the program terminated, and whether you're happy or sad about that having happened. Using a language feature that handles everything for you is way easier than trying to do it yourself.
If you're on a Unix-flavoured system, then the termination of a process that you've forked will generate a SIGCHLD signal. This means your program can do other things your child process is running.
Catching the SIGCHLD signal varies depending upon your language. In Perl, you set a signal handler like so:
use POSIX qw(:sys_wait_h);
sub child_handler {
while ((my $child = waitpid(-1, WNOHANG)) > 0) {
# We've caught a process dying, its PID is now in $child.
# The exit value and other information is in $?
}
$SIG{CHLD} \&child_handler; # SysV systems clear handlers when called,
# so we need to re-instate it.
}
# This establishes our handler.
$SIG{CHLD} = \&child_handler;
There's almost certainly modules on the CPAN that do a better job than the sample code above. You can use waitpid with a specific process ID (rather than -1 for all), and without WNOHANG if you want to have your program sleep until the other process has completed.
Be aware that while you're inside a signal handler, all sorts of weird things can happen. Another signal may come in (hence we use a while loop, to catch all dead processes), and depending upon your language, you may be part-way through another operation!
If you're using Perl on Windows, then you can use the Win32::Process module to spawn a process, and call ->Wait on the resulting object to wait for it to die. I'm not familiar with all the guts of Win32::Process, but you should be able to wait for a length of 0 (or 1 for a single millisecond) to check to see if a process is dead yet.
In other languages and environments, your mileage may vary. Please make sure that when your other process dies you check to see how it dies. Having a sub-process die because a user killed it usually requires a different response than it exiting because it successfully finished its task.
All the best,
Paul
Are you on Windows ? If so, the following should solve the problem - you need to pass the process ID:
bool WaitForProcessExit( DWORD _dwPID )
{
HANDLE hProc = NULL;
bool bReturn = false;
hProc = OpenProcess(SYNCHRONIZE, FALSE, _dwPID);
if(hProc != NULL)
{
if ( WAIT_OBJECT_0 == WaitForSingleObject(hProc, INFINITE) )
{
bReturn = true;
}
}
CloseHandle(hProc) ;
}
return bReturn;
}
Note: This is a blocking function. If you want non-blocking then you'll need to change the INFINITE to a smaller value and call it in a loop (probably keeping the hProc handle open to avoid reopening on a different process of the same PID).
Also, I've not had time to test this piece of source code, but I lifted it from an app of mine which does work.
Most operating systems its generally the same kind of thing....
you record the process ID of the program in question and just monitor it by querying the actives processes periodically
In windows at least, you can trigger off events to do it...
Umm you can't, this is an impossible task given the nature of it.
Let's say you have a program foo that takes as input another program foo-sub.
Foo {
func Stops(foo_sub) { run foo_sub; return 1; }
}
The problem with this all be it rather simplistic design is that quite simply if foo-sub is a program that never ends, foo itself never ends. There is no way to tell from the outside if foo-sub or foo is what is causing the program to stop and what determines if your program simply takes a century to run?
Essentially this is one of the questions that a computer can't answer. For a more complete overview, Wikipedia has an article on this.
This is called the "halting problem" and is not solvable.
See http://en.wikipedia.org/wiki/Halting_problem
If you want analyze one program without execution than it's unsolvable problem.