• 【Linux】多进程基础--信号


    信号

    • 信号是向进程传递消息的一种机制,发生事件时通过信号向进程进行通知,从而改变进程的行为,信号在软件层次上模拟中断,也叫软件中断,处理优先级较高
    • 对于前台进程可以通过特殊的字符发送信号,例如Ctrl+C即给当前进程发送一个SIGINT中断信号。
    • kill命令也是向进程发送信号,可以通过kill -l查询信号,例如kill -9 pid即向pid进程发送终止信号
    • 信号通信较为简单、不能携带大量的信息、优先级较高
    • 信号集有阻塞信号集和未决信号集,通过位视图标识,阻塞信号是指阻止信号被处理,未决是一种状态指的是从信号产生到信号处理的这段时间,先查询未决再查询阻塞。
    • 信号的默认处理动作为:Term终止进程、lgn忽略信号、Core终止进程并生成Core文件默认大小为0,可以通过ulimit -a查看,并通过ulimit -c unlimited进行大小修改即可看到相应文件,一般和gdb配合使用在gdb中可以通过core-file core查看文件、Stop暂定进程、Cont继续执行被暂停的进程,man 7 signal可查询详细信息

    常见信号

    信号代号信号名称说 明默认动作
    1SIGHUP该信号让进程立即关闭,然后重新读取配置文件之后重启终止进程
    2SIGINT程序中止信号,用于中止前台进程。相当于输出 Ctrl+C 快捷键终止进程
    3SIGQUIT和SIGINT类似, 但由QUIT字符(通常是Ctrl+/)来控制。 进程在因收到SIGQUIT退出时会产生core文件, 在这个意义上类似于一个程序错误信号。终止进程
    8SIGFPE在发生致命的算术运算错误时发出。不仅包括浮点运算错误,还包括溢出及除数为 0 等其他所有的算术运算错误终止进程、产生core文件
    9SIGKILL用来立即结束程序的运行。本信号不能被阻塞、处理和忽略。般用于强制中止进程终止进程–强制
    11SIGSEGV试图访问未分配给自己的内存, 或试图往没有写权限的内存地址写数据,段错误终止进程产生core文件
    13SIGPIPE管道破裂。这个信号通常在进程间通信产生,比如采用FIFO(管道)通信的两个进程,读管道没打开或者意外终止就往管道写,写进程会收到SIGPIPE信号。终止进程
    14SIGALRM时钟定时信号,计算的是实际的时间或时钟时间。alarm 函数使用该信号终止进程
    15SIGTERM正常结束进程的信号,kill 命令的默认信号。如果进程已经发生了问题,那么这个信号是无法正常中止进程的,这时我们才会尝试 SIGKILL 信号,也就是信号 9终止进程
    17SIGCHLD子进程结束时, 父进程会收到这个信号。忽略信号
    18SIGCONT该信号可以让暂停的进程恢复执行。本信号不能被阻断继续/忽略
    19SIGSTOP该信号可以暂停前台进程,相当于输入 Ctrl+Z 快捷键。本信号不能被阻断终止进程

    信号定时函数

    #include 
    
    1. unsigned int alarm(unsigned int seconds);
    //alarm不阻塞,程序正常执行,在指定的时间后向进程发送一个信号,通常是SIGALRM信号。
    //参数seconds:指定多少秒后发送SIGALRM信号给调用进程。如果seconds为0,则取消任何现有的闹钟(如果有的话)。
    //返回值:如果之前已有闹钟设置,该函数返回剩余的秒数并从新设置的秒数计时,如果没有设置过闹钟,返回0。
    //SIGALRM:默认终止当前进程
    
    #include 
    
    2. int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);
    //成功时返回0,出错时返回-1,并设置errno
    //周期性定时可代替alarm
    //which:指定要设置的计时器类型,一般为ITIMER_REAL真实时间返回SIGALRM
    //value:指向一个itimerval结构的指针
    struct itimerval {
       struct timeval it_interval; /* 下一次间隔 */
        struct timeval it_value;   /* 多长时间开始计时 */
    };
    struct timeval{
        time_t tv_sec;//秒数
        suseconds_t tv_usec;//微秒
    }
    ovalue(可选):指向一个itimerval结构的指针,用来存储之前设置的定时器值。如果不需要旧值,可以传入NULL。
    
    struct itimerval new_value;
    //设置间隔
    new_value.it_interval.tv_sec=2;
    new_value.it_interval.tv_usec=0;
    
    //设置延迟
    new_value.it_value.tv_sec=3;
    new_value.it_value.tv_usec=0;
    
    //使用
     if (setitimer(ITIMER_REAL, &new_value, NULL) == -1) {
            perror("setitimer error");
            return 1;
        }
    

    信号捕捉函数

    #include 
    
    1. typedef void (*sighandler_t)(int);//函数指针,输入int返回void
    sighandler_t signal(int signum, sighandler_t handler);
    
    //成功情况下,返回以前的信号处理函数指针。
    //signum:要处理的信号编号,如SIGINT(2,对应Ctrl+C中断)、SIGTERM(15,程序终止信号)等。
    //handler:处理函数指针。可以是以下几种情况之一:
    /*
    SIG_DFL:恢复信号的默认处理行为。
    SIG_IGN:忽略该信号。
    自定义函数指针:当进程接收到signum信号时,将调用此函数.
    */
    
    //具体使用
    void myalarm(int num){
        std::cout<<"捕捉的信号编号为"<

    信号集

    • 信号集有阻塞信号集和未决信号集,通过位视图标识,阻塞信号是指阻止信号被处理,未决是一种状态指的是从信号产生到信号处理的这段时间,先查询未决再查询阻塞。
    #include 
    
    int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
    //设置内核信号,包括阻塞、接触阻塞、替换
    //成功时返回0,失败时返回-1,并设置errno。
    //how:决定如何对内核阻塞信号集处理,可以是以下值之一:
    /*
    SIG_BLOCK:将set指定的信号集所包含的信号添加到当前的阻塞信号集中。
    SIG_UNBLOCK:从当前的阻塞信号集中移除set指定的信号。
    SIG_SETMASK:将当前的阻塞信号集设置为set指定的信号集,完全替换原有集合。
    */
    //set:指向一个sigset_t类型的指针,表示要修改的信号集合。具体操作根据how参数决定。
    //oldset一般为NULL
    
    
    int sigpending(sigset_t *set);
    //查询当前进程中哪些信号是未决的,不会清除未决信号的状态。
    //成功时返回0。出错时返回-1,并设置errno。
    //set:指向sigset_t类型的指针,用来存放查询结果。函数执行成功后,set中将包含当前进程所有未决信号的集合。
    
    
    //具体使用
    sigset_t set;//创建自定义信号集
    sigemptyset(&set);//初始化
    sigaddset(&set,SIGQUIT)
    sigaddset(&set,SIGINT)//信号集中加入SIGQUIT、SIGINT信号,位视图法,将相应信号位置1
    
    sigprocmask(SIG_BLOCK,&set,NULL)//将内核中相应的信号阻塞,位视图法,将相应信号位置1
    sigpending(&set)//查询哪些信号是未决的
    
  • 相关阅读:
    PHP8的数组-PHP8知识详解
    免费IP类api接口:含ip查询、ip应用场景查询、ip代理识别、IP行业查询...
    Vue条件渲染
    Go语学习笔记 - gorm使用 - 数据库配置、表新增 Web框架Gin(七)
    Mysql - 索引
    java Spring框架 XML配置和注解配置的区别
    香橙派orangepi ubuntu 安装安装redis
    走进江苏作家诗人胭脂茉莉|世界读书日
    【Leetcode HOT100】不同路径 c++
    如何理解 HTTP 状态码?
  • 原文地址:https://blog.csdn.net/csdnabcaq/article/details/139439540