New dragon
New dragon

Reputation: 5

how to send a sigterm signal

In my following program i have two processes( the father and the child) both do the same thing but we want to figure out how will finish his task first. There is a randomized number of seconds both will sleep causing the challenge of who finishes first more random. Both are sending signals to the other process, when five signals have been recieved the process will then send a SIGTERM to the other process signaling that it has finished first. that other process will print that the opponent process has won. My problem is with sending that sigterm signal to the other process, ive tried kill function, singal function and dont know where is my mistake and what to try next. So any help would e=be appreciated below is my code:

 //--------including--------------
 #include <stdio.h>
 #include <stdlib.h>
 #include <time.h>
 #include <sys/types.h>
 #include <signal.h>
 #include <unistd.h>
//-------global----------------
int sig1_counter=0;
int sig2_counter=0;
//-------prototypes--------------
void catch_sigusr1(int sig_num) ;
void catch_sigusr2(int sig_num) ;
void do_son() ;
void do_dad() ;
//--------main------------------
int main (){
pid_t pid;
srand((unsigned)time(NULL));

signal(SIGUSR1, catch_sigusr1) ;
signal(SIGUSR2, catch_sigusr2) ;

pid = fork() ;

switch(pid) {
case -1 : perror("fork() failed") ;
          exit(EXIT_FAILURE) ;
case 0 : do_son() ;
          exit(EXIT_SUCCESS) ;
default: do_dad() ;
          exit(EXIT_SUCCESS) ;
 }


    return EXIT_SUCCESS;
 }
//-------functions-------------------
void do_son() {
   int i ;
 for (i=0;i<10;i++)
 {
    int sleep_time=rand()%4;
    sleep(sleep_time);
    int num=rand()%2;
    if (num==0)
        kill(getpid(), SIGUSR1) ;
    else
        kill(getpid(), SIGUSR2);
 }
 }
//---------------------------------
void do_dad() {
   int i ;

  for (i=0;i<10;i++)
  {
    int sleep_time=rand()%4;
    sleep(sleep_time);
    int num=rand()%2;
    if (num==0)
        kill(getpid(), SIGUSR1) ;
    else
        kill(getpid(), SIGUSR2);
   }
  }
//---------------------------------
 void catch_sigusr1(int sig_num) {
     signal(SIGUSR1, catch_sigusr1);
     printf(" process %d got signal SIGUSR1\n", getpid()) ;
   if (sig_num==SIGTERM)
  {
    printf("process %d win\n", getpid());
    exit(EXIT_SUCCESS);
  }
   sig1_counter++;
  if (sig1_counter==5)
  {
    printf(" process %d surrender\n", getpid()) ;
    kill(getpid(),SIGTERM);        // here we have a mistake
    //signal(SIGTERM,catch_sigusr2);  // !!!!!!!!!!!
    exit(EXIT_SUCCESS);
   }
 }
//---------------------------------
 void catch_sigusr2(int sig_num) {
   signal(SIGUSR2, catch_sigusr2) ;
   printf(" process %d got signal SIGUSR2\n", getpid()) ;
  if (sig_num==SIGTERM)
  {
    printf("process %d win\n", getpid());
    exit(EXIT_SUCCESS);
  }
   sig2_counter++;
  if (sig2_counter==5)
  {
    printf(" process %d surrender\n", getpid()) ;
    kill(getpid(),SIGTERM);
    //signal (SIGTERM,catch_sigusr1);
    exit(EXIT_SUCCESS);
  }
} 

Upvotes: 0

Views: 4478

Answers (1)

paxdiablo
paxdiablo

Reputation: 881623

Both your do_son() and do_dad() functions send signals to getpid(), which means they are signalling only themselves rather than each other.

In order to signal each other, you need:

  • do_dad() to send the signal to pid, the return value from fork() being the child PID; and
  • do_son() to send the signal to getppid(), the parent PID, noting the use of non-sexist terms in the system call :-)

In other words, something like this in your main function:

switch (pid = fork()) {
    case -1:
        perror("fork() failed");
        break;
    case 0:
        do_both(getppid());
        break;
    default:
        do_both(pid);
        break;
 }

The reason there's no distinct parent and child function any more is that the only difference is which PID gets signalled. Because you're passing that in as a parameter, you can combine the two functions:

void do_both(pid_t other) {
    for (int i = 0; i < 10; i++) {
        int sleep_time = rand() % 4;
        sleep(sleep_time);
        if ((rand() % 2) == 0)
            kill(getpid(), SIGUSR1);
        else
            kill(getpid(), SIGUSR2);
     }
 }

Upvotes: 1

Related Questions