信号编程之signal函数

  • 作用1:站在应用程序的角度,注册一个信号处理函数。
  • 作用2:忽略信号、设置信号默认处理 信号的安装和恢复
  • 相关宏定义
    • typedef void (*__sighandler_t) (int);
    • #define SIG_ERR ((__sighandler_t) -1)
    • #define SIG_DFL ((__sighandler_t) 0)
    • #define SIG_IGN ((__sighandler_t) 1)
  • 函数原型:
    __sighandler_t signal(int signum, __sighandler_t handler);
  • 参数

    • signal是一个带signum和handler两个参数的函数,准备捕捉或屏蔽的信号由参数signum给出,接收到指定信号时将要调用的函数由handler给出
    • handler这个函数必须有一个int类型的参数(即接收到的信号代码),它的返回类型是void
    • handler也可以是下面两个特殊值:
      • SIG_IGN 屏蔽/忽略该信号
      • SIG_DFL 恢复默认行为
    • 返回值
      The signal() function returns the previous value of the signal handler, or SIG_ERR on error.
  • 基本使用

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

#include <sys/types.h>
#include <unistd.h>
#include <signal.h>

int flag = 0;

void my_handle(int sig_num)
{
  printf("recv num:%d\n",sig_num);//收到SIGINT只是打印信号码
  if(sig_num == SIGQUIT)//收到SIGQUIT信号会改变flag--main函数退出死循环
  {
    flag = 1;
  }
}

int main()
{
  signal(SIGINT,my_handle);//注册新号和其处理函数
  signal(SIGQUIT,my_handle);

  while(flag == 0)
  {
    pause();//死循环等待信号
  }

  printf("parent over!!\n");//收到SIGQUIT会执行到这里
  return 0;
}
  • 忽略信号–可用于避免僵尸进程
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/stat.h>

int main()
{

  pid_t pid;

  signal(SIGCHLD,SIG_IGN);
  pid = fork();

  if(-1 == pid)
  {
    perror("fork");
    exit(0);//子进程很快结束
  }
  else if(0 == pid)
  {
    printf("child\n");
    exit(0);
  }

  while(1)
  {
    pause();//父进程一直不结束--但由于忽略子进程结束--不会有僵尸进程/defunct
  }
  return 0;
}
  • 信号注册和恢复
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/stat.h>


void my_handle(int sig_num)
{
  printf("recv num:%d\n",sig_num); 
}

int main()
{

  signal(SIGINT,my_handle);//指定接收到SIGINT 的行为为自定义的处理函数
  printf("如果你键入a字符,那么将恢复 SIGINT 的行为\n");
  while(getchar() != 'a')
  {
    pause();
    printf("如果你键入a字符,那么将恢复 SIGINT 的行为\n");
  }

  signal(SIGINT,SIG_DFL);//恢复 SIGINT 的行为
  while(1);
  printf("parent over!!\n");
  return 0;
}
  • 使用signal的返回值
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/stat.h>


void my_handle(int sig_num)
{
  printf("recv num:%d\n",sig_num); 
}

int main()
{

  __sighandler_t old = signal(SIGINT, my_handle);
    if (SIG_ERR == old)
    {
        perror("signal err"); //errno   
   exit(-1);
    }
  printf("如果你键入a字符,那么将恢复 SIGINT 的行为\n");
  while(getchar() != 'a')
  {
    pause();
    printf("如果你键入a字符,那么将恢复 SIGINT 的行为\n");
  }

  signal(SIGINT,SIG_DFL);//恢复 SIGINT 的行为
  while(1);
  printf("parent over!!\n");
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值