• signal()信号操作


    一、函数描述

    #include <signal.h>

    typedef void (*sighandler_t)(int);
    sighandler_t signal(int signum, sighandler_t handler);

    signal()会将接收到的signum信号交给hander(可以是SIG_IGN, SIG_DFL)处理,signal()的功能会跟随着Unix版本的变化而变化。

    当这个进程收到这个signum信号后,处理如下:

      ①如果handler是SIG_IGN,此信号被忽略

      ②如果handler是SIG_DFL,将由系统按默认的方法处理

      ③指定给handler函数来处理此信号。

    返回值:signal()返回信号处理程序的前一个值,或者返回错误的SIG_ERR

    注意:signal()在多线程进程中的影响是未指定的.

    1.kill -l 列出所有信号;ctrl + c 产生SIGINT信号

    2.#include <unistd.h>
    int pause(void);

    pause()会导致调用进程(或线程)进入休眠状态,直到收到信号,此时会终止进程或引起信号捕获函数的调用。

    pause() 仅在信号被捕获并且信号捕获函数返回时才返回。 在这种情况下,pause()返回-1,errno被设置为EINTR。

    3.select() poll() epoll() 都是基于信号的!

    4.kill函数将信号发送给进程,raise函数允许进程向自身发送信号;
    int kill(pid_t pid, int sig); //kill()系统调用可用于将任何信号发送到任何进程组或进程

    5.int raise(int sig);
    raise()向调用进程或线程发送信号(本线程/进程).在单线程进程中它等同于kill(getpid(), sig);
    在多线程进程中它等同于pthread_kill(pthread_self(), sig);
    如果信号导致处理程序被调用,那么raise()在信号处理程序返回后才会返回,成功返回0

    6.用户自定义信号:SIGUSR1 和 SIGUSR2的使用:kill -USR1 processID 和 kill -USR2 processID

    7.unsigned int alarm(unsigned int seconds); alarm函数设置了一个定时器,当定时器到了就发送SIGALRM信号

    8.void abort(void); //让进程捕捉SIGABRT的意图是,在进程终止前由其执行所需的清理操作

    abort()首先开放SIGABRT信号,然后向调用进程发送此信号。 这将导致进程异常终止,除非SIGABRT信号被捕获且信号处理程序不返回。
    如果abort()函数导致进程终止,则所有打开的流将关闭并刷新。
    如果SIGABRT信号被忽略,或者被返回的处理程序捕获,abort()函数仍将终止该进程。此函数是通过先恢复SIGABRT的缺省处置,
    然后再次产生此信号来完成此操作的。abort()函数永远不会返回。

    二、使用例子

    用户信号的使用:
    #include <stdio.h> #include <unistd.h> #include <signal.h> static void sig_usr_fun(int signo) { if (signo == SIGUSR1) { printf("received SIGUSR1! "); } else if (signo == SIGUSR2) { printf("receive SIGUSR2! "); } } int main() { if (signal(SIGUSR1, sig_usr_fun) == SIG_ERR) { printf("signal1 error! "); } if (signal(SIGUSR1, sig_usr_fun) == SIG_ERR) { printf("signal2 error! "); } for (;;) { pause(); } return 0; }

    kill -SIGUSR1 15504
    #include <stdio.h>
    #include <signal.h>
    #include <stdlib.h>
    int ext = 0;
    static void sig_fun(int signo)  
    {
        ext = 1;
        printf("Catch Signal SIGINT
    ");
    }
    
    int main()
    {
        char *p = NULL;
        int count = 0;
        p = malloc(100);
        signal(SIGINT, sig_fun);
        
        while(1){
            if(ext){
                break;
            }
            count++;
        }
    
        if(p != NULL){
            free(p);
         p = NULL; printf(
    "p has been freed! "); } }

    收到信号强制终止时释放资源,以免内存泄漏
    #include <stdio.h>
    #include <signal.h>
    #include <stdlib.h>
    void catch_signal(int sign)
    {
        switch(sign)
        {
        case SIGALRM:
            printf("SIGALRM Signal
    ");
        }
    }
    int main()
    {
        signal(SIGALRM, catch_signal);
        alarm(3);
        printf("================
    ");
        pause();
        return 0;
    }
  • 相关阅读:
    pthread_mutex_init函数与pthread_mutexattr_init函数
    DPDK收发包全景分析
    Linux Bond的原理及其不足
    Cisco VPP启动流程
    组网基础之深入解析二层组播
    vpp命令总结
    全面挖掘Java Excel API 使用方法
    MySQL的varchar定义长度到底是字节还是字符
    MYSQL 用户管理
    MySql中的变量定义
  • 原文地址:https://www.cnblogs.com/hellokitty2/p/7816849.html
Copyright © 2020-2023  润新知