zoukankan      html  css  js  c++  java
  • APUE读书笔记:关于sigsuspend

    sigsuspend是一个原子操作,为了防止信号丢失而存在的,具体含义看下函数原型。

    int sigsuspend(const sigset_t *mask);

    先忽略参数,sigsuspend完成的操作是阻塞进程的运行,直到有信号的产生。这样来看与另一个函数的作用相同。pause()

    加上参数来理解,sigsuspend完成的操作是阻塞进程的运行,如果信号是mask参数设置的信号集,那么该信号是pending状态,而不会影响进程的阻塞状态,意思是进程仍然在阻塞中,直到不在信号集中的信号出现,进程能够继续执行。注意:如果之前确实有在mask信号集中的信号出现,该信号会在sigsuspend函数返回后被进程所捕获,完成自定义的或者默认的信号响应函数。

    实验:sigsuspend对SIGINT信号设置屏蔽,在阻塞期间先发送SIGINT信号,再发送SIGUSR1信号

    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <signal.h>
    
    static int proc_sig=0;
    sigset_t zeromask;
    
    void pr_mask(const char* str);
    
    void proc_usr1(int)
    {
        printf("proc_usr1
    ");
        pr_mask("In sigusr1:");
    };
    
    
    int main()
    {
        sigset_t sigset, oldmask, waitmask;
        
        signal(SIGUSR1, proc_usr1);
    
        sigprocmask(0, NULL, &oldmask);
    
        //sigaddset(&sigset, SIGUSR1); 
        //sigprocmask(SIG_BLOCK, &sigset, NULL);
        //pr_mask("Block SIGUSR1");
    
        pr_mask("Before suspend");
    
        sigaddset(&waitmask, SIGINT);
        sigsuspend(&waitmask);
    
        pr_mask("After suspend:");
    
        //sleep(12);
        //sigprocmask(SIG_UNBLOCK, &sigset, NULL);
        //pr_mask("Unblock SIGUSR1");
    
        sleep(12);
    
        return 0;
    }
    
    void pr_mask(const char * str)
    {
        sigset_t sigset;
        sigprocmask(0, NULL, &sigset);
    
        printf("%s:", str);
    
        if (sigismember(&sigset, SIGCHLD)) printf("SIGCHLD ");
        if (sigismember(&sigset, SIGALRM)) printf("SIGALRM ");
        if (sigismember(&sigset, SIGUSR2)) printf("SIGUSR2 ");
        if (sigismember(&sigset, SIGUSR1)) printf("SIGUSR1 ");
        if (sigismember(&sigset, SIGSTOP)) printf("SIGSTOP ");
        if (sigismember(&sigset, SIGKILL)) printf("SIGKILL ");
    if (sigismember(&sigset, SIGINT)) printf("SIGINT "); printf(
    " "); }

    运行:先ctrl+C(发送SIGINT信号),后发送信号SIGUSR1(kill -SIGUSR1 pid)

    输出:

    Before suspend:
    ^Cproc_usr1
    In sigusr1::SIGUSR1 SIGINT

    输出解释:第一行输出表示该进程未设置信号屏蔽字

    第二行看到Ctrl+c的信号,之后的是信号响应函数proc_usr1的输出

    第三行也是proc_usr1的输出当前进程的屏蔽字有SIGINT(由sigsuspend设置),还有SIGUSR1(不懂为啥SIGUSR1也会出现在当前屏蔽字中)

    对于上面的问题:为啥SIGUSR1也会出现在当前屏蔽字中?

    假设当前进程接受到了SIGUSR1信号,进入proc_usr1的信号处理函数,在函数执行期间,又收到了一个SIGUSR1信号,进程会怎么处理呢?

    os应该先接受该信号,在SIGUSR1的响应函数结束后,os把该信号扔到当前进程,当前进程继续响应该SIGUSR1。

    这样就能够解释了为啥SIGUSR1信号被屏蔽了,再某个信号的响应函数内,该信号一定会被设置为阻塞的,即响应函数处理时间内当前进程不要响应该信号。

  • 相关阅读:
    新概念第二册(1)--英语口语听力课1
    外企面试课程(一)---熟悉常见的缩略词
    公司 邮件 翻译 培训 长难句 结课
    workflow
    公司 邮件 翻译 培训 长难句 20
    公司 邮件 翻译 培训 长难句 19
    Engineering Management
    公司 邮件 翻译 培训 长难句 18
    公司 邮件 翻译 培训 长难句 17
    第14.5节 利用浏览器获取的http信息构造Python网页访问的http请求头
  • 原文地址:https://www.cnblogs.com/helww/p/3815202.html
Copyright © 2011-2022 走看看