11月3日笔记并发3_信号

本文详细介绍了Linux系统中的信号处理机制,包括各种信号的意义、信号的处理方式及其相关API函数。信号作为进程间通信的一种方式,其处理机制对于理解系统运作至关重要。

1.信号
    信号 是进程间通信的一种方式,这种方式没有传输数据
    在内核中传递的是一个信号(整数)    信号的表示是一个整数
    不同的信号值 代表不同含义 
    当然用户也可以自定义信号 既然是自定义的信号 那么含义也有程序员来解释

                                Terminate 终止

        Signal        Value        Action   Comment
    ────────────────────────────────────────────────────────
       SIGHUP        1       Term    Hangup detected on controlling terminal
                                      or death of controlling process
                                        控制终端的挂起操作,或者控制进程死亡时
                                        控制终端上的所有进程都会收到SIGHUP信号

       SIGINT        2        Term    Interrupt from keyboard
                                        从键盘上收到中断信号 CTRL + C

                                      Core 输出信号 然后终止
       SIGQUIT       3       Core    Quit from keyboard
                                        退出信号 CTRL + Z

       SIGILL        4           Core    Illegal Instruction
                                        非法指令

       SIGABRT       6       Core    Abort signal from abort(3)
                                        调用 abort这个函数 进程会受到这个信号

       SIGFPE        8        Core    Floating-point exception
                                        浮点运算异常机会产生这个信号

        SIGKILL       9       Term    Kill signal
        SIGSTOP   17,19,23    Stop    Stop process
                                            程序员自定义的信号

       SIGSEGV      11       Core    Invalid memory reference
                                        内存的非法引用 就会SIGSEGV信号
                                            段错误
       SIGPIPE      13       Term    Broken pipe: write to pipe with no
                                     readers; see pipe(7)
                                     管道只有写数据端 没有读数据端的时候就会产生这个信号

       SIGALRM      14       Term    Timer signal from alarm(2)
                                        定时信号,在进程调用alarm时
                                        超时产生这个信号  你定的闹钟时间到了 就会给你发这个信号
       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
                                        子进程停止或者中止时父进程会收到这个信号
       SIGCONT   19,18,25    Cont    Continue if stopped
       
       SIGTSTP   18,20,24      Stop    Stop typed at terminal
       SIGTTIN    21,21,26      Stop    Terminal input for background process
       SIGTTOU   22,22,27     Stop    Terminal output for background process

        进程在收到一个信号时 通常会有三种处理方式
        (1)默认行为
            term Core收到一个信号时 采用操作系统的默认行为。
            大部分信号的默认行为时把进程给干掉
            只有一个SIGCHLD被忽略
        
        (2)捕捉该信号
            把一个信号跟用户自定义的信号处理函数关联
          收到该信号的时 去执行关联的信号处理函数
        
        (3)忽略该信号


2.信号的处理过程
    通过 软件中断/软中断 去实现

    信号处理函数其实是在 中断上下文执行
        信号处理函数 -》 软中断函数

        //写信号处理函数 是线程安全的/可重入

    中断上下文 就是中断环境下 中断模式


3. linux下信号相关的API函数
(1)发送信号
    kill

    NAME
        kill - send signal to a process

    SYNOPSIS
        #include <sys/types.h>
        #include <signal.h>
            kill可以发送一个信号给一个指定的进程或多个进程
        int kill(pid_t pid, int sig);

      pid_t pid:
            pid > 0: pid表示信号接收者的进程
            pid = 0; 发送信号给调用进程同组的所有进程
            pid = -1 发送信号给所有进程
            pid < -1 发送信号给组id等于pid绝对值的所有进程

      int sig : 要发送的信号

            返回值   成功(至少有一个进程接收到该信号) 返回0
                          失败返回-1 同时errno被设置


    raise 发信号给自己

    NAME
        raise - send a signal to the caller

    SYNOPSIS
        #include <signal.h>

        int raise(int sig);

            raise(sig) <=>kill(getpid(),sig);
        


alarm

    NAME
        alarm - set an alarm clock for delivery of a signal

    SYNOPSIS
        #include <unistd.h>

        unsigned int alarm(unsigned int seconds);

                        seconds 多少秒后 发送一个闹钟信号
                        0 表示取消闹钟

                        返回值
                        返回上一个闹钟的剩余时间

                        alarm(10);
                        alarm(20);///20秒中之后收到了闹钟信号
                                    //前面的闹钟就被替换                    


        每一个进程都有一个属于自己的闹钟,闹钟时间到了
        进程就会收到一个SIGALRM的信号,同一时刻
        一个进程只有一个闹钟生效

        闹钟会在时间结束的时候给你发一个信号 SIGALRM 给本进程


        大部分是信号的默认行为都是杀死这个进程
        那么我们又不是都希望杀死它
        那么怎么改变行为


(2) 捕捉信号 改变信号的处理方式

        NAME
            signal - ANSI C signal handling

        SYNOPSIS
            #include <signal.h>

            typedef void (*sighandler_t)(int);

            sighandler_t是什么?
            sighandler_t是一个函数指着的类型。它可以用来定义函数指针变量

            sighandler_t signal(int signum, sighandler_t handler);

          int signum: 你要改变哪一个信号的处理方式
        sighandler_t handler:捕捉到这个信号后 要调用的那个函数
                            1.自定义函数
                                void (*sighandler_t)(int);
                                没有返回值 但是有一个int参数
                                这个参数是用来保存信号的值的

                                void MySignalHandler(int sig)
                                {
                                    中间就是处理过程
                                }

                            2.SIG_DFL:default 采用系统默认的处理方式
                            3.SIG_IGN:忽略该信号

                返回值
                    成功返回该信号的上一个处理方式 你上一次调用了那个函数
                    失败返回SIG_ERR 同时errno被设置
    
    练习 我们的程序,通常可以被CTRL+C干掉
    那么现在你牛逼了 你能不能写一个程序 让ctrl+C 干不掉它 顺便嘲讽一波

代码:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>


void MySignalHandler(int sig)
{
    switch (sig)
    {
    case SIGINT:
        printf("\n傻了吧,干不掉我\n");
        break;
    
    default:
        break;
    }
}

int main(int argc,char *argv[])
{

    signal(SIGINT,MySignalHandler);
    //int res = pause();
    //printf("res = %d\n",res);

    while (1);
    
}


///////////


输入 ctrl+C 会输出 printf 内的内容 

输入 ctrl+Z 会退出程序 


    (3)等待信号的到来
    pause 让进程停在哪里 等待某个信号的到来
            直到收到了信号

            NAME
                pause - wait for signal

            SYNOPSIS
                #include <unistd.h>

                int pause(void);

            DESCRIPTION
                pause()  causes  the  calling  process (or thread) to sleep until a signal is
                delivered that either terminates the process or causes the  invocation  of  a
                signal-catching function.

            RETURN VALUE
                pause()  returns  only when a signal was caught and the signal-catching func‐
                tion returned.  In this case, pause() returns -1, and errno is set to EINTR.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值