Hosein Zarifi
Hosein Zarifi

Reputation: 69

sending signal between two child process

I create two children from the parent in the main program. The first and second child executes a program (signalSender) after their creation(alongside with the pid of the other child as an argument). signalSender has signal handler and is used for sending signal between process. The pid of the second child is given as zero as argument when first child executes signalShooter. The pid of the first child is given as argument when the second child executes sigShooter.

1) I want to find the pid of the first child via signal handler after second child sends the signal to first child. I tried to save it to global variable pid_t pid2 but it does not work.

2)I also have to send signal between these two children 100 times but i dont know where to use 'for loop' and ‘wait’ signal.

The main program:

#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>

int main()
{
    pid_t pid1,pid2,wid;
  char *my_args[5];
  int aInt = 368
     char str[15];
   pid1 = fork();
       if (pid1 < 0)
    {
      fprintf(stderr, ": fork failed: %s\n", strerror(errno));

      exit(1);

    }
    if(pid1 == 0)
    {
      my_args[0] = "sigperf1";
      my_args[1] = "0";
      my_args[2] = NULL;
      execv("signalSender",my_args);
      fprintf(stderr,"signalSender cannot be executed...");
      exit(-1);
    }

    pid2 = fork();

    if(pid2 < 0)
    {
       fprintf(stderr, ": fork failed: %s\n", strerror(errno));
       exit(1);
    }

    if(pid2 == 0)
    {
      sprintf(str, "%d", pid1);
      my_args[0] = "sigperf1";
      my_args[1] = str;
      my_args[2] = NULL; 
     // printf("this is converted = %s\n",my_args[1]);
      execv(“signalSender",my_args);
      fprintf(stderr,"signalSender cannot be executed...");
      exit(-1);
    }
wid = wait(NULL);

}

The signalSender:

#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <ctype.h>

pid_t pid2;
struct sigaction act;

void sighandler(int signum, siginfo_t *info, void *ptr)
{
    printf("Received signal %d\n", signum);
    printf("Signal originates from process %lu\n",
        (unsigned long)info->si_pid);
        pid2 = info->si_pid;
}

int main(int argc,char **argv)
{ 
    memset(&act, 0, sizeof(act));
    act.sa_sigaction = sighandler;
    act.sa_flags = SA_SIGINFO;
    sigaction(SIGUSR1, &act, NULL);

    pid_t current, pidOther;
    current = getpid();
    pidOther = atol(argv[1]);

    if(pidOther != 0) // we are in the second child
    {
        kill(pidOther,SIGUSR1); //sending signal from second child to first 
    }

    if(pidOther == 0) // we are in the first child 
    {
        kill(pid2,SIGUSR1);
    }

    return 0;
}

Upvotes: 2

Views: 1861

Answers (1)

dbush
dbush

Reputation: 225344

You have a synchronization issue here.

Both child processes start at roughly the same time. So you can't predict which one will kill the other first. If the first child runs kill first, it will pass 0 as the pid which will kill every process in the process group. Also, each child process quits immediately after calling kill, so one may exit before the other has a chance to send it a signal.

You need to introduce some type of synchronization method. A simple way to do this is to have the second process sleep briefly before calling kill to give the first process a chance to start up. Similarly, the first process should call pause, which will tell it to wait until it receives a signal.

Once you do that, then each process can call pause and kill in a loop to go back and forth.

if(pidOther != 0) // we are in the second child
{
    sleep(1);    // wait for first child to start
    kill(pidOther,SIGUSR1); //sending signal from second child to first 
    for (i=0;i<5;i++) {
        pause();
        kill(pidOther,SIGUSR1);
    }
}

if(pidOther == 0) // we are in the first child 
{
    pause();   // wait until we get a signal from the second child
    kill(pid2,SIGUSR1);
    for (i=0;i<5;i++) {
        pause();
        kill(pid2,SIGUSR1);
    }
}

Upvotes: 0

Related Questions