LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   signals (http://www.linuxquestions.org/questions/programming-9/signals-938892/)

mcy 04-09-2012 09:48 AM

signals
 
hello everyone, i am trying to understand signals and i wrote that little program:

int main(){

pid1=fork();
pid2=fork();

if(pid1==0){
printf("pid1: I am child %d\n",getpid());
}

else if(pid2==0){
printf("pid2: I am child %d\n",getpid());
}

else
printf("I am parent %d\n",getpid());
}

and the output is:

pid1: I am child 8702
pid1: I am child 8701
pid2: I am child 8703
I am father 8700

my question is why there are two pid1 and not two pid2?
thanks

crabboy 04-09-2012 10:20 AM

That is because the child of the first fork will run the fork for pid2, so there are two processes running the second fork.
Code:

pid1=fork()
  child1
    pid2=fork()
      child 3

pid2=fork()
  child2

and the parent processes is 4 total

Nominal Animal 04-09-2012 10:23 AM

Please use [CODE] [/CODE] tags around your code to make it more readable.

Quote:

Originally Posted by mcy (Post 4648374)
Code:

pid1=fork();
pid2=fork();

if(pid1==0){
  printf("pid1: I am child %d\n",getpid());
}

else if(pid2==0){
  printf("pid2: I am child %d\n",getpid());
}

my question is why there are two pid1 and not two pid2?

You obviously have four processes:
  1. The original process, let's call it A
  2. The child B created by the first fork in the original process
  3. The child C created by the second fork in the original process
  4. The child D created by the second fork in process B
The values of pid1 and pid2 before the if clauses are:
  1. pid1==nonzero, pid2==nonzero
  2. pid1==zero, pid2==nonzero
  3. pid1==nonzero, pid2==zero
  4. pid1==zero, pid2==zero
The first if clause will match in both B and D. This is why you get two pid1 outputs: one by B, the first child created by the original process, and one by D, the child created by the second child created by the original process.

Because the second clause is else if, it is only evaluated when the first one did not match; i.e., only for A, the original process, and for C, the second child created by the original process. Because pid2 is zero only for the latter, you only get one pid2 output, printed by C, the second child created by the original process.

This is a very good example of why you should not do forks in succession: it is too easy to miss that all processes created by the first fork will execute the following forks, unless you add the check that makes sure only the original process forks.

mcy 04-09-2012 10:56 AM

These were very helpful! Thanks for your explanation! I've got one more question if u could help me.. I cant understand how and when to use kill(pid,SIGUSR1) and signal(SIGUSR1,handler);
Thank u again! :)

dwhitney67 04-09-2012 11:22 AM

Quote:

Originally Posted by mcy (Post 4648425)
These were very helpful! Thanks for your explanation! I've got one more question if u could help me.. I cant understand how and when to use kill(pid,SIGUSR1) and signal(SIGUSR1,handler);
Thank u again! :)

I believe the use of signal() has been deprecated in favor of using sigaction(), which offers more features.

Here's a simple example:
Code:

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

void sigHandler(int signo)
{
    printf("Signal Handler called with signo = %d\n", signo);
}


int main()
{
    struct sigaction act;

    memset(&act, 0, sizeof(struct sigaction));

    act.sa_handler = sigHandler;

    sigaction(SIGUSR1, &act, 0);

    sleep(2);

    kill(getpid(), SIGUSR1);

    return 0;
}

To compile the program above:
Code:

gcc -D_POSIX_SOURCE signal.c

mcy 04-09-2012 01:16 PM

ok thank u very much! :)


All times are GMT -5. The time now is 06:31 AM.