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信号被屏蔽了,再某个信号的响应函数内,该信号一定会被设置为阻塞的,即响应函数处理时间内当前进程不要响应该信号。

  • 相关阅读:
    js插件ztree使用
    asp.net错误页和asp.net mvc错误页设置
    C#实现Excel的导入导出
    ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
    iOS开发UI篇—UITabBarController简单介绍
    iOS开发UI篇—字典转模型
    iOS开发UI篇—从代码的逐步优化看MVC
    iOS开发UI篇—九宫格坐标计算
    iOS开发UI篇—transframe属性(形变)
    iOS开发UI篇—懒加载
  • 原文地址:https://www.cnblogs.com/helww/p/3815202.html
Copyright © 2011-2022 走看看