zoukankan      html  css  js  c++  java
  • apue读书笔记第十章

    apue啃到第十章了,随着内容越来越深入,发现似乎hold不住了,因此在这里记录下我的一些心得

    1,signal的函数声明为什么是这样?

      如果要返回一个函数指针就需要这么些,至于为什么可以参看:http://blog.csdn.net/zimingjushi/article/details/6554801,这篇文章解释了一些东西,但是依然让人很迷惑:(除了typedef外)没有更简单直观的方法吗?

           我觉得这涉及到c语言语法分析的一些东西,以后有时间再仔细研究

    2,《不可靠的信号》中的两个例子说明了什么?

          a,由于信号动作被复位,嵌套的中断会引起问题

          b,如果用户想用pause等待一个信号的话,会丢失掉pause之前就引发的信号,这一段时间可能很重要,此时应该用另一个函数

    3,sigaction的陷阱

        “sa_sigaction和sa_handler字段的实现可能使用了同一存储区” ,一开始没有注意这句话,结果我在程序中清除了一下sa_sigaction,信号函数死活不能被调用

        看了一下声明,它们确实是同一地址:

       

    union
          {
        /* Used if SA_SIGINFO is not set.  */
        __sighandler_t sa_handler;
        /* Used if SA_SIGINFO is set.  */
        void (*sa_sigaction) (int, siginfo_t *, void *);
          }

    4,系统调用重启

        下面的程序演示了不被重启的效果:

       后台模式运行程序,然后kill -USR1 pid,然后fg调到前台运行,结果程序直接返回-1,并不读取任何输入

    typedef void (*sigf)(int);
    inline sigf msignal(int n,sigf f)
    {
        struct sigaction act;
        struct sigaction act1;
        act.sa_handler=f;
        act.sa_flags=0;
        sigemptyset(&act.sa_mask);
        act.sa_flags|=SA_INTERRUPT;
        //act.sa_flags|=SA_RESTART;
        int r=sigaction(n,&act,&act1);
        printf("r: %d %d\n",r,n);
        if(r<0)return SIG_ERR;
        return act1.sa_handler;
    }
    static void sig_usr(int sid)
    {
        printf("sig: %d\n",sid);
    
    }
    
    int main()
    {
        sigf f1;
        if((f1=msignal(SIGUSR1,sig_usr))==SIG_ERR)printf("%s\n","err");
        if(msignal(SIGUSR2,sig_usr)==SIG_ERR)printf("%s\n","err");
        int a='!';
        a=getchar();
        sprintf("%d %c\n",a,a);
        //while(a=getchar())putchar(a);    
        return 1;
    }

    4,信号调用不可重入的函数会怎么办?

       会引发未知的问题,可能会崩溃,也可能输出错误的答案,我这里运行书上的例子的话,信号getpwnam根本不能返回,但是书上是崩溃(为什么?)

    5,SIGCLD的旧语义有什么问题?

        设置SIGCLD处理函数会立即检查一下子进程的状态,可能立即调用SIGCLD处理函数,如果在信号处理函数中在wait之前再次设置SIGCLD的话,会引起堆栈溢出

         必须在wait之后在重设SIGCLD

    6,信号的生命周期:产生-未决-递送,大多数UNIX不对信号进行排队,重复的信号只保留最后一个     

    7,sleep的实现对alarm的影响,sleep可以选择复位上次设置的alarm,也可以不复位,依赖于实现

        在linux上实验,sleep覆盖了原先的alarm没有复位

    8,如果不设置SA_NODEFER,在进入信号处理函数后,当前信号被自动加入到信号屏蔽字中,退出函数后复位

        这是为了防止同类信号的嵌套处理,这样保证了信号处理函数不会被重入

        如果这样的话,10-4节描述的那个问题就不存在了,因为此时不会去处理同一个信号(这主要是旧的不可靠信号的问题)

        但是为什么在信号处理函数中再调用raise和kill仍然可以调到本信号的处理函数呢?

    9,10-15的代码使用为什么要设置canjump?

        为了保证在信号发生时sigsetjump已经被设置

       

  • 相关阅读:
    C#入门(3)
    C#入门(2)
    C#入门(1)
    JNI工程搭建及编译
    Java-NestedClass(Interface).
    ConCurrent in Practice小记 (4)
    Java Annotation 注解
    Android使用ViewPager做轮播
    ConCurrent in Practice小记 (3)
    ConCurrent in Practice小记 (2)
  • 原文地址:https://www.cnblogs.com/mightofcode/p/2841822.html
Copyright © 2011-2022 走看看