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已经被设置

   

原文地址:https://www.cnblogs.com/mightofcode/p/2841822.html