为什么我无法捕捉到父母发送给孩子的信号? [英] Why I can't catch the signal in the child which is sent by parent?

查看:80
本文介绍了为什么我无法捕捉到父母发送给孩子的信号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是学习C语言中的信号,我想将信号从父级发送到子级,但是我不明白为什么处理程序在这里不起作用...

我的代码:

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>

void handler(int signumber){
  printf("Signal with number %i has arrived\n",signumber);
}

int main(){

  sigset_t sigset;
  sigemptyset(&sigset); //empty signal set
  sigaddset(&sigset,SIGTERM); //SIGTERM is in set
  //sigfillset(&sigset); //each signal is in the set
  sigprocmask(SIG_BLOCK,&sigset,NULL); //signals in sigset will be blockedhere

  signal(SIGTERM,handler); //signal and handler is connetcted

  pid_t child=fork();
  if (child>0)
  {
    printf("I'm parrent\n");
    printf("Waits 2 seconds, then send a SIGTERM %i signal (it is blocked)\n",SIGTERM);
    sleep(2);
    kill(getppid(),SIGTERM); 
    printf("I sent it.\n");   
  }
  else
  {
    wait(NULL);
    sleep(2);
    printf("I'm the child wainting for signal.\n");

    sigprocmask(SIG_UNBLOCK,&sigset,NULL); 


    int status;
    wait(&status);
    printf("Child process ended\n");
  }
  return 0;
}

这是结果:

I'm parrent
Waits 2 seconds, then send a SIGTERM 15 signal (it is blocked)
I'm the child wainting for signal.
Child process ended
I sent it.

还有一件事,我知道,我必须使用sigsuspend(sigset);而不是处理程序,因为 printf在处理程序,但是在这种情况下如何使用?

解决方案

等待主要用于收获子状态(通常用于观察子状态变化). 在孩子中使用它没有多大意义. 是的,您可以使用sigsuspend等待信号. 看起来可能像这样:

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


#define WRITE(Str) (void)write(1,Str,strlen(Str))
void handler(int signumber)
{
    WRITE("Signal arrived\n");
}

int main(){

  sigset_t sigset;
  sigemptyset(&sigset); //empty signal set
  sigaddset(&sigset,SIGTERM); //SIGTERM is in set
  sigprocmask(SIG_BLOCK,&sigset,NULL); //signals in sigset will be blockedhere

  signal(SIGTERM,handler); //signal and handler is connetcted

  pid_t child=fork();
  if(0>child) return EXIT_FAILURE;
  if (child>0) {
    int status;
    printf("I'm the parent\n");
    printf("Waits 2 seconds, then send a SIGTERM %i signal (it is blocked)\n",SIGTERM);
    sleep(2);
    kill(child,SIGTERM);
    printf("I sent it.\n");
  }
  else
  {
    sigemptyset(&sigset); //the child has a different addr-space
                          //so this won't affect the parent
    printf("I'm the child waiting for signal.\n");
    sigsuspend(&sigset);
    printf("Child process ended\n");

  }
  return 0;
}

有关更多信息,请参见各个系统功能的手册页.您也应该检查返回码,即使大多数这些特定功能通常都不会失败,除非您将它们称为错误(尽管有些这样做,例如,如果内存不足,fork()可能实际上会失败). /p>

I just learning about signals in C, and I want to send a signal from parent to child, but I can't understand why the handler isn't working here...

My code:

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>

void handler(int signumber){
  printf("Signal with number %i has arrived\n",signumber);
}

int main(){

  sigset_t sigset;
  sigemptyset(&sigset); //empty signal set
  sigaddset(&sigset,SIGTERM); //SIGTERM is in set
  //sigfillset(&sigset); //each signal is in the set
  sigprocmask(SIG_BLOCK,&sigset,NULL); //signals in sigset will be blockedhere

  signal(SIGTERM,handler); //signal and handler is connetcted

  pid_t child=fork();
  if (child>0)
  {
    printf("I'm parrent\n");
    printf("Waits 2 seconds, then send a SIGTERM %i signal (it is blocked)\n",SIGTERM);
    sleep(2);
    kill(getppid(),SIGTERM); 
    printf("I sent it.\n");   
  }
  else
  {
    wait(NULL);
    sleep(2);
    printf("I'm the child wainting for signal.\n");

    sigprocmask(SIG_UNBLOCK,&sigset,NULL); 


    int status;
    wait(&status);
    printf("Child process ended\n");
  }
  return 0;
}

And this is the result:

I'm parrent
Waits 2 seconds, then send a SIGTERM 15 signal (it is blocked)
I'm the child wainting for signal.
Child process ended
I sent it.

And one more thing, I know, I have to use sigsuspend(sigset); instead of handler, because the printf isn't safe in handler, but How can I use it in this case?

解决方案

Wait is mainly for reaping child statuses (generally for observing child status changes). Using it in the child doesn't make much sense. Yes, you can use sigsuspend to wait for the signal. It could look like this:

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


#define WRITE(Str) (void)write(1,Str,strlen(Str))
void handler(int signumber)
{
    WRITE("Signal arrived\n");
}

int main(){

  sigset_t sigset;
  sigemptyset(&sigset); //empty signal set
  sigaddset(&sigset,SIGTERM); //SIGTERM is in set
  sigprocmask(SIG_BLOCK,&sigset,NULL); //signals in sigset will be blockedhere

  signal(SIGTERM,handler); //signal and handler is connetcted

  pid_t child=fork();
  if(0>child) return EXIT_FAILURE;
  if (child>0) {
    int status;
    printf("I'm the parent\n");
    printf("Waits 2 seconds, then send a SIGTERM %i signal (it is blocked)\n",SIGTERM);
    sleep(2);
    kill(child,SIGTERM);
    printf("I sent it.\n");
  }
  else
  {
    sigemptyset(&sigset); //the child has a different addr-space
                          //so this won't affect the parent
    printf("I'm the child waiting for signal.\n");
    sigsuspend(&sigset);
    printf("Child process ended\n");

  }
  return 0;
}

See the man pages of the individual system functions for more information. You should be checking return codes too, even though most of these particular functions generally don't fail unless you call them wrong (some do, though, e.g., fork() can quite realistically fail if you're out of memory).

这篇关于为什么我无法捕捉到父母发送给孩子的信号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆