orpqK
orpqK

Reputation: 2785

Signal and SIGCHLD, what does it do?

i am asked to find all the possible outputs in this question:

#define N 4
int val = 9;
void handler(sig) {
   val += 3;
   return;
}
int main() {
  pid_t pid;
  int i;
  signal(SIGCHLD,handler);
  for (i=0;i<N;i++) {
    if ((pid =fork()) == 0) {
        val -= 3;
        exit(0);
    }
  }
  for (i=0;i<N;i++) {
    waitpid(-1,NULL,0);
  }
  printf("val = %d\n",val);
}

I do not know what the line signal(SIGCHLD, handler) does. I only found the following:

SIGABRT - abnormal termination.
SIGFPE - floating point exception.
SIGILL - invalid instruction.
SIGINT - interactive attention request sent to the program.
SIGSEGV - invalid memory access.
SIGTERM - termination request sent to the program.

what does SIGCHLD do? Can you also explain the for loop in this question as well?

and what necessary libraries do I need to compile and run this code?

Upvotes: 9

Views: 47202

Answers (4)

Andrew Henle
Andrew Henle

Reputation: 1

The output is even less constrained than @ArseniyAlekseyev's answer.

Per 5.1.2.3 Program execution, paragraph 5 of the (draft) C11 standard (bolding mine):

When the processing of the abstract machine is interrupted by receipt of a signal, the values of objects that are neither lock-free atomic objects nor of type volatile sig_atomic_t are unspecified, as is the state of the floating-point environment. The value of any object modified by the handler that is neither a lock-free atomic object nor of type volatile sig_atomic_t becomes indeterminate when the handler exits, as does the state of the floating-point environment if it is modified by the handler and not restored to its original state.

Any result is possible given that, and even though the use of fork() and SIGCHLD strongly imply a POSIX system, the semantics of signal() are not guaranteed by POSIX:

When a signal occurs, and func points to a function, it is implementation-defined whether the equivalent of a:

signal(sig, SIG_DFL);

is executed ...

The parent process could simply end upon receipt of the second SIGCHLD and emit nothing if the default handling of SIGCHLD is to exit.

Upvotes: 1

jim mcnamara
jim mcnamara

Reputation: 16379

Odd program.

What I think it is trying to shows you is what SIGCHLD causes and how a variable in a child process being changed by the child, has no effect in the parent.

When you fork() you create a child process. Sound familiar? The parent process ( the one that called fork() ) receives the signal. The handler is executed. When you run the program you should see out of 21.

This is because val is incremented by three every time the signal handler is executed 9 + ( 3*4)=21. The code creates four children.

The child process

val -= 3;
exit(0);

decrements val. But because this happens in another process, not the original child, it does not touch the "original" val variable because it has its own local copy.

Upvotes: 8

Arseniy Alekseyev
Arseniy Alekseyev

Reputation: 63

I believe @jim mcnamara's answer does not list all possible outputs.

9+(3*k) for 1 <= k <= 4 should be possible because multiple signals can get collapsed into one.

Upvotes: 2

Ram
Ram

Reputation: 445

When you fork a child process from a parent process, the SIGCHLD is set but the handler function is NOT executed. After the child exits, it trips the SIGCHLD and thus causes the code in the handler function to execute...

Upvotes: 8

Related Questions