zoukankan      html  css  js  c++  java
  • 信号

    kill -l  查看全部信号

    前32个  unix经典信号

    后32个称为实时信号(自定义信号)

    kill可以导致一个进程被终止

    90%的信号,默认都使进程终止

     1.2 信号机制

    信号的三大行为和五种默认动作   

    核心已转储  一定是Core  动作

        SIGHUP            1               Term         Hangup detected on controlling terminal or death of controlling process
             SIGINT              2               Term         Interrupt from keyboard
             SIGQUIT           3               Core          Quit from keyboard
             SIGILL               4               Core           Illegal Instruction
             SIGABRT           6               Core           Abort signal from abort(3)
             SIGFPE              8               Core           Floating point exception
             SIGKILL             9               Term          Kill signal
             SIGSEGV          11              Core          Invalid memory reference          (段错误核心已转储)
             SIGPIPE           13              Term         Broken pipe: write to pipe with no readers
             SIGALRM         14              Term          Timer signal from alarm(2)
             SIGTERM         15              Term          Termination signal
             SIGUSR1          30,10,16   Term         User-defined signal 1
             SIGUSR2          31,12,17   Term         User-defined signal 2
             SIGCHLD          20,17,18   Ign            Child stopped or terminated          子进程结束给父进程发送一个SIGCHILD
             SIGCONT         19,18,25    Cont         Continue if stopped
             SIGSTOP          17,19,23    Stop         Stop process
             SIGTSTP           18,20,24    Stop         Stop typed at tty              (ctrl+z)只能暂停终端前台进程
             SIGTTIN           21,21,26    Stop          tty input for background process
             SIGTTOU          22,22,27    Stop         tty output for background process

    jobs  

    唤醒进程:fg(唤醒到前台运行) bg(唤醒到后台运行)

     1.3 信号产生种类

    kill(-1,9)   -1是指给所有进程发送信号    执行这句话后导致计算机重启

    sig为0时,用于检测,特定为pid进程是否存在,如不存在,返回-1。

    1.4 信号产生原因

    1) SIGHUP:当用户退出shell时,由该shell启动的所有进程将收到这个信号,默认动作为终止进程
    2)SIGINT:当用户按下了<Ctrl+C>组合键时,用户终端向正在运行中的由该终端启动的程序发出此信号。默认动作为终止里程。3)SIGQUIT:当用户按<ctrl+>组合键时产生该信号,用户终端向正在运行中的由该终端启动的程序发出些信号。默认动作为终止进程。
    4)SIGILL:CPU检测到某进程执行了非法指令。默认动作为终止进程并产生core文件
    5)SIGTRAP:该信号由断点指令或其他trap指令产生。默认动作为终止里程并产生core文件。
    6 ) SIGABRT:调用abort函数时产生该信号。默认动作为终止进程并产生core文件。
    7)SIGBUS:非法访问内存地址,包括内存对齐出错,默认动作为终止进程并产生core文件。
    8)SIGFPE:在发生致命的运算错误时发出。不仅包括浮点运算错误,还包括溢出及除数为0等所有的算法错误。默认动作为终止进程并产生core文件。
    9)SIGKILL:无条件终止进程。本信号不能被忽略,处理和阻塞。默认动作为终止进程。它向系统管理员提供了可以杀死任何进程的方法。
    10)SIGUSE1:用户定义的信号。即程序员可以在程序中定义并使用该信号。默认动作为终止进程。
    11)SIGSEGV:指示进程进行了无效内存访问。默认动作为终止进程并产生core文件。
    12)SIGUSR2:这是另外一个用户自定义信号,程序员可以在程序中定义并使用该信号。默认动作为终止进程。1
    13)SIGPIPE:Broken pipe向一个没有读端的管道写数据。默认动作为终止进程。
    14) SIGALRM:定时器超时,超时的时间由系统调用alarm设置。默认动作为终止进程。
    15)SIGTERM:程序结束信号,与SIGKILL不同的是,该信号可以被阻塞和终止。通常用来要示程序正常退出。执行shell命令Kill时,缺省产生这个信号。默认动作为终止进程。
    16)SIGCHLD:子进程结束时,父进程会收到这个信号。默认动作为忽略这个信号。
    17)SIGCONT:停止进程的执行。信号不能被忽略,处理和阻塞。默认动作为终止进程。
    18)SIGTTIN:后台进程读终端控制台。默认动作为暂停进程。
    19)SIGTSTP:停止进程的运行。按下<ctrl+z>组合键时发出这个信号。默认动作为暂停进程。
    21)SIGTTOU:该信号类似于SIGTTIN,在后台进程要向终端输出数据时发生。默认动作为暂停进程。
    22)SIGURG:套接字上有紧急数据时,向当前正在运行的进程发出些信号,报告有紧急数据到达。如网络带外数据到达,默认动作为忽略该信号。
    23)SIGXFSZ:进程执行时间超过了分配给该进程的CPU时间,系统产生该信号并发送给该进程。默认动作为终止进程。
    24)SIGXFSZ:超过文件的最大长度设置。默认动作为终止进程。
    25)SIGVTALRM:虚拟时钟超时时产生该信号。类似于SIGALRM,但是该信号只计算该进程占用CPU的使用时间。默认动作为终止进程。
    26)SGIPROF:类似于SIGVTALRM,它不公包括该进程占用CPU时间还包括执行系统调用时间。默认动作为终止进程。
    27)SIGWINCH:窗口变化大小时发出。默认动作为忽略该信号。
    28)SIGIO:此信号向进程指示发出了一个异步IO事件。默认动作为忽略。
    29)SIGPWR:关机。默认动作为终止进程。
    30)SIGSYS:无效的系统调用。默认动作为终止进程并产生core文件。
    31)SIGRTMIN~(64)SIGRTMAX:LINUX的实时信号,它们没有固定的含义(可以由用户自定义)。所有的实时信号的默认动作都为终止进程。

     1.4 信号集处理函数
    sigset_t为信号集,可sizeof(sigset_t)察看
    int sigemptyset(sigset_t *set)
    int sigfillset(sigset_t *set)
    int sigaddset(sigset_t *set, int signo)
    int sigdelset(sigset_t *set, int signo)
    int sigismember(const sigset_t *set, int signo)

    unix经典信号不支持排队(最多有一个)

    例:利用捕捉函数测试,当我们同时按很多次ctrl + c 时,只执行两次

    当第一个信号a(编号为2)发来时,通过未决信号集,未决信号集置1,然后通过阻塞信号集,到达Handler,未决信号集置0,执行函数,在执行过程中,系统将阻塞信号集的2号信号置1,此时,还有新的信号b(2)通过未决信号集,然后未决信号集置1 ,但此时,阻塞信号集2号信号也为1,所以信号b就在未决信号和阻塞信号集之间,其余到来的信号,由于未决信号集2号信号为1,都被忽略,当函数执行完毕,则阻塞信号集置0,信号b通过,所以只执行两次函数。

    测试代码:

    #include <stdio.h>
    #include <unistd.h>
    #include <signal.h>
    void sig_func(int n)
    {
        int flag = 3;
        for(int i = 0; i < 3;i++)
        {
            printf("---flag:%d-----
    ",flag);
            flag--;
            sleep(1);
        }
    }
    int main()
    {
        struct sigaction act,oldact;
        act.sa_handler = sig_func;
        act.sa_flags  = 0;
        sigemptyset(&act.sa_mask);
        sigaction(SIGINT,&act,&oldact);
        while(1);
    }

    结果:

    alarm返回没定时够的秒数(定时10s但是在过了2s后,程序被终端则返回8s)

     时序竞态:原子功能,信号之间用全局资源用可重入函数

    测试代码:

    #include <stdio.h>
    #include <unistd.h>
    #include <signal.h>
    void alm(int n)
    {}
    unsigned int mysleep(unsigned int seconds)
    {
        //因为时间资源的竞争,导致程序引发灾难性后果,时序竟态
        int reval;
        sigset_t set,oldset;
        sigemptyset(&set);
        sigaddset(&set,SIGALRM);
        sigprocmask(SIG_BLOCK,&set,&oldset);
        sigemptyset(&oldset);
        signal(SIGALRM,alm);
        reval = alarm(seconds);
        if(reval == -1)
            perror("Alarm call Failed:");
        //pause();
        sigsuspend(&oldset);
    }
    int main()
    {
        while(1)
        {
            printf("Two seconds..
    ");
            mysleep(2);
        }
    }

    用pause函数存在的问题:当计时器开始计数,但时间片没有了,去执行其他进程,过程中发回SIGALRM,当时间片轮转回来时,会先处理信号,然后再执行pause(),这样线程就会永远不被唤醒。

    int pause(void)
           使调用进程挂起,直到有信号递达,如果递达信号是忽略,则继续挂起
    int sigsuspend(const sigset_t *mask)
           1.以通过指定mask来临时解除对某个信号的屏蔽,
           2.然后挂起等待,
           3.当被信号唤醒sigsuspend返回时,进程的信号屏蔽字恢复为原来的值

  • 相关阅读:
    Luogu P3346 [ZJOI2015]诸神眷顾的幻想乡
    SP10570 LONGCS
    Luogu P3975 [TJOI2015]弦论
    hihocoder #1457 : 后缀自动机四&#183;重复旋律7
    Luogu SP8222 NSUBSTR
    SP7258 SUBLEX
    Luogu P4070 [SDOI2016]生成魔咒
    [清华集训2016]组合数问题
    [NOIP2018TG]保卫王国
    [note]克鲁斯卡尔重构树
  • 原文地址:https://www.cnblogs.com/Lune-Qiu/p/9346092.html
Copyright © 2011-2022 走看看