如何发送sigterm信号

时间:2017-11-20 15:19:31

标签: c signals

在我的下一个程序中,我有两个进程(父亲和孩子)都做同样的事情,但我们想弄清楚如何完成他的任务。两个人都会有一个随机的秒数,这会导致谁先完成随机挑战。两者都向另一个进程发送信号,当收到五个信号时,进程将向另一个进程发送SIGTERM,表示它已先完成。其他进程将打印对手进程已赢得。我的问题是将sigterm信号发送到另一个进程,我尝试了杀死函数,单一函数,不知道我的错误在哪里以及接下来要尝试什么。因此,以下是我的代码:

 //--------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);
  }
} 

1 个答案:

答案 0 :(得分:1)

您的do_son()do_dad()函数都会向getpid()发送信号,这意味着它们只是发信号而不是相互信号。

为了互相发出信号,你需要:

  • do_dad()将信号发送到pidfork()的返回值是子PID;和
  • do_son()将信号发送到父PID的getppid(),注意在系统调用中使用非性别歧视用语: - )

换句话说,在你的主要功能中有类似的东西:

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

没有明显的父子功能的原因是唯一的区别是哪个PID发出信号。因为您将其作为参数传递,所以您可以将这两个函数组合在一起:

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);
     }
 }