zoukankan      html  css  js  c++  java
  • signal()函数

    函数原型

    void (*signal(int sig,void(*func)(int)))(int);

    指定使用sig指定的信号编号处理信号的方法。参数func指定程序可以处理信号的三种方式之一:

    1. l  默认处理(SIG_DFL):          信号由该特定信号的默认动作处理
    2. l  忽略信号(SIG_IGN):      忽略信号,即使没有意义,代码执行仍然继续。
    3. l  函数处理程序:                 定义一个特定的函数来处理信号。

    或SIG_DFL要么SIG_IGN被设置为程序启动时每个支持信号的默认信号处理行为。

    参数:

    SIG设置处理功能的信号值,以下宏常量表达式标识标准信号值:

    信号

    SIGABRT

    (信号终止)异常终止,例如由…发起的退出功能

    SIGFPE

    (信号浮点异常)错误的算术运算,比如零分频或导致溢出的运算(不一定是浮点运算)

    SIGILL

    (信号非法指令)无效的功能图像,例如非法指令。这通常是由于代码中的损坏或尝试执行数据

    SIGINT

    (信号中断)交互式注意信号。通常由应用程序用户生成

    SIGSEGV

    (信号分段违规)对存储的无效访问:当程序试图在已分配的内存之外读取或写入时。

    SIGTERM

    (信号终止)发送到程序的终止请求。

    每个库实现可以提供可以与此函数一起使用的附加信号值宏常量。

    注意:并不是所有的运行环境都需要生成自动信号,即使在上述特定情况下也是如此,尽管所有运行环境都必须通过显示调用生成的信号来生成提高功能

    FUNC

    指向函数的指针。这是程序员定义的函数,也可以是以下预定义函数之一:

    SIG_DFL

    默认处理:信号由该特定信号的默认操作处理

    SIG_IGN

    忽略信号:忽略信号

    如果是一个函数,它应该遵循以下原型(使用C链接)

    void handler_function(int parameter)

    返回值

    返回类型与参数func类型相同。

    如果请求成功,则该函数返回指向特定处理函数的指针,该函数在调用 之前负责处理该信号(如果有的话)。或者SIG_DFL要么SIG_IGN。如果在调用之前信号由默认处理程序处理或被忽略,则相应的,如果该功能尚未能成功注册新的信号处理程序,则返回SIG_ERR和错误号可以设置成正值。

    /***
    signal.c
    ***/
     #include<stdio.h>
     #include<signal.h>
     
     sig_atomic_t signaled = 0;
     
     void my_handler(int param)
     { 
         signaled = 1;
     }
     
     int main()
     {
         void (*prev_handler)(int); 
     
         prev_handler = signal(SIGINT,my_handler);
       
         raise(SIGINT);
     
         printf("signaled is %d.
    ",signaled);
     }

    运行结果:

    root@ubuntu:/mnt/hgfs/ShareWindows/shiyanlou/C/Flappy_Bird# gcc signal.c -o signal

    root@ubuntu:/mnt/hgfs/ShareWindows/shiyanlou/C/Flappy_Bird# ./signal

    signaled is 1.

    #include<stdio.h>
    typedef void (*sighandler_t)(int);
    sighandler_t signal(int signum,sighandler_t handler);

    第一个参数是要捕捉的信号(查看信号: kill –l , 9号SIGKILL信号不能被捕捉)

    第二个参数表示我们要对信号进行的处理方式。

    信号处理方式一般有三种:

    1.忽略此信号(SIG_IGN):

    /***
    sig_ign.c
    ***/
    #include<stdio.h>
    #include<unistd.h>
    #include<signal.h>
    
    int main()
    {
        signal(2,SIG_IGN);
        while(1)
        {
            printf("23333
    ");
            sleep(1);
        }
        return 0;
    }

    执行程序会进入死循环,Ctrl+c进程不会停止,因为我们对Ctrl+c产生的2号SIGINT信号做了忽略处理,Ctrl+z(SIGQUIT)退出。

    2.执行该信号的默认处理动作(SIG_DEL):

    /***
    sig_def.c
    ***/
    #include<stdio.h>
    #include<signal.h>
    #include<unistd.h>
    
    int main()
    {
        signal(2,SIG_DFL);
        while(1)
        {
            printf("23333
    ");
            sleep(1);
        }
        return 0;
    }

    执行程序时,对Ctrl+c设置的默认动作处理,此时ctrl+c就可以停止程序。

     3.提供一个信号处理函数,要求内核在处理该信号时切换到用户态执行这个处理函数,这种方式称为捕捉一个信号:

    /***
    sig_catch.c
    ***/
    #include<stdio.h>
    #include<signal.h>
    #include<unistd.h>
    
    void handler(int signo)
    {
        printf(" catch a signal:%d
    ",signo);
    }
    
    int main()
    {
        signal(2,handler);
        while(1)
        {
            printf("2333
    ");
            sleep(1);
        }
        return 0;
    }

    运行结果:

    此时按下ctrl+c会被捕捉到,不会中断程序了。

    一些常用的信号宏定义:

    Signal

    Description

    SIGABRT

    由调用abort函数产生,进程非正常退出

    SIGALRM

    由alarm函数设置的timer超时或setitimer函数设置的interval timer超时

    SIGBUS

    某种特定的硬件异常,通常由内存访问引起

    SIGCANCEL

    由SOLARIS Thread Library内部使用,通常不会使用

    SIGCHLD

    进程Terminate或Stop的时候,SIGCHLD会发送给他的父进程。缺省情况下会该Signal会忽略

    SIGCONT

    当被stop的进程恢复运行的时候,自动发送

    SIGEMT

    和实现相关的硬件异常

    SIGFPE

     数字相关的异常,如被0除,浮点溢出。

    SIGFREEZE

    Solaris专用,Hiberate或者Suspended时候发送。

    SIGHUP

    发送给具有Terminal的Controlling Process,当terminal被disconnect时候发送

    SUGILL

    非法指令异常

    SIGINFO

    BSD signal。由Status Key产生,通常是CTRL+T。发送给所有Foreground Group的进程

    SIGINT

    由Interrupt Key产生,通常是CTRL+C或DELETE。发送给所有的ForeGround FROUP的进程

    SIGIO

    异步IO事件

    SIGIOT

    实现相关的硬件异常,一般对应SIGABRT

    SIGKILL

    无法处理和忽略,中止某个程序

    SIGLWP

    由Solaris Thread Library内部使用

    SIGPIPE

    在reader终止之后写Pipe的时候发送

    SIGPOLL

    当某个事件发送给Pollable Device的时候发送

    SIGPROF

    Setitimer指定的Profilling Interval Timer所产生

    SIGPWR

    和系统相关。和UPS相关

    SIGQUIT

    输入Quit Key的时候,(CTRL + )发送给所有的Foreground Group的进程

    SIGSEGV

    非法内存访问

    SIGSTKFLT

    Linux专用,数学协处理器的栈异常

    SIGSTOP

    中止进程,无法处理和忽略

    SIGSYS

    非法系统调用

    SIGTERM

    请求中止进程,kill命令缺省发送

    SIGTHAW

    Solaris专用,从Suspend恢复时发送

    SIGTRAP

    实现相关的硬件异常,一般是调试异常

    SIGTSTP

    Suspend Key,一般是Ctrl+Z,发送给所有的ForeGround Group的进程

    SIGTTIN

    当BackGround Froup的进程尝试读取Terminal的时候发送

    SIGTTOU

    当Background Group的进程尝试写Terminal的时候发送

    SIGURG

    当out-of-band data接收的时候可能发送

    SIGUSR1

    用户自定义signal 1

    SIGUSR2

    用户自定义signal 2

    SIGVTALRM

    setitimer函数设置的Virual Interval Timer超时的时候

    SIGTAITING

    Solaris Thread Library内部实现专用

    SIGWINCH

    当Terminal的窗口大小改变的时候,发送给Foreground Group的所有进程

    SIGXCPU

    当CPU时间限制超时的时候

    SIGXFSZ

    进程超过文件大小限制

    SIGXRES

    Solaris专用,进程超过资源限制的时候发

  • 相关阅读:
    springboot springcloud zuul 过滤器
    springboot springcloud eureka 熔断器
    javaweb servlet filter
    maven nexus 搭建私服(二)
    springboot springcloud zuul 网关入门
    springboot springcloud 配置中心
    springboot springcloud eureka 入门
    java rabbitmq
    java jvm调优
    maven nexus 搭建私服(一)
  • 原文地址:https://www.cnblogs.com/wanghao-boke/p/11577391.html
Copyright © 2011-2022 走看看