UNIX环境高级编程 第十章 信号小结

大二下学期就已经看完了这本书,但是一直没有小结,最近在看UNP2,涉及到这一块,乘机总结一下.。

  1.  
    信号实质是一个软中断,每一个信号都有一个名字,SIGXXX。

    首先,我信号分为实时信号(可靠信号),不可靠信号。

    可靠信号指的是有实时行为的,即

    1:信号是排队的

    2:当有多个SIGRTMIN到SIGRTMAX的信号范围的解阻塞信号排队时,较小的值优先与较大的值。 

    3:当非实时信号提交时,信号处理函数只需要该信号的值,但是实时信号需要更多的内容

    比如实时处理函数的原型是:

    void func(int signo, siginfo_t*, void* context);
    typedef struct {
        int si_sigo;
        int si_code;
        union sigval si_value;
    } siginfo_t
    

    其中,si_code 表示信号产生源,比如SI_ASYNCIO(表示有某个异步IO请求的的完成产生),si_value 是application -specific value

    而信号处理函数的注册,却不仅仅是signal函数,而是sigaction函数,其原型是:

    #include<signal.h>
    
    int signation(int sigo, const struct sigaction * restrict act, struct sigaction * restrict oact );
    
    struct sigaction
    {
        void (*sa_handler)(int);    //addr of singal handler;
        sigset_t sa_mask;     //addition singal to block;
        
        int sa_flags;     // singal option: SA_XXX
        void  (*sa_sigaction)(int , siginfo_t* , void* ); 
        //addr of signal handler if SA_SIGINFO set;
    }
    
    

     

    这个是信号里面的实时信号的内容。(按照UNP2第五章内容理解的,上一学期只是看了,并未有这么比较清楚的例子)
     
    下面我按照书本的顺序,总结一下。

    函数signal

    原型: 
    void (*signal (int signal, void (*func)(int))) (int);

    这个函数有点复杂。简化如下:

    typedef void Sigfunc(int);
    Sigfunc* signal(int, Sigfunc(int));

    其中 有以下几个定义;

    #define SIG_ERR (void (*) ()) -1;
    #define SIG_DFL (void(*) ()) 0;
    #define SIG_IGN (void (*)()) 1;

    这些都是很常规的函数。

     

    考虑当函数中执行exec函数,那么新的代码段的信号处理函数和以前的需要变化吗?即以前注册的信号处理函数会怎么办?
    当执行力exec函数后,以前注册的信号处理函数全部变为默认的,以前SIG_DEL的保持不变。

    以前注册的函数地址,在执行exec后很有可能变得没有意义。。。所以要变为默认的。

    在执行fork函数后,应为子进程在开始时候复制了子进程内存映像,所以函数地址还是有意义的。
     

    中断的系统调用

    早期unix系统的一个特性是; 当进程在执行一个低速系统调用而阻塞期间捕获到一个信号,则该系统调用就被中断,不再执行,该系统调用出错,其erron设置为EINTR;

    低速系统调用是指可能会使进程永远阻塞的一类系统调用。

    1,如某些类型文件数据不存在(如读管道,终端设备,网络设备),则读操作可能会使调用者永远阻塞。也就是阻塞到读上面.
    2,如果数据不能被相同的文件类型接受,则写操作可能会被调用者永远阻塞。也就是写阻塞。
    3.在某种条件发生之间打开某些类型文件
    4.pause

    5.ioctl

    6.进程间通讯函数。比如FIFO中,read在不设置阻塞的情况下会阻塞,知道有数据写入。
    这里值得注意的是,有些系统引入自动重启功能。

    这在各个系统中有不同的定义。但是新的函数sigaction函数里面提供了是否字段重启的选项(但并非每个实现都是这样);

    可重入函数

    可重入函数是指在中断函数调用的函数,其调用不会影响被中断的函数。
    函数不可重用的原因有三:
    1.使用静态数据结构
    2.调用malloc或free
    3.标准IO

    SIGCLD

    这个主要讲的是在的system V中,对SIGCLD处理有点不同。
    1)如果进程明确的将信号配置位SIG_IGN,那么调用进程将不产生僵尸进程。虽然其SIG_DEL的处理方式是“忽略”掉该信号,但两者不同。如果设置了SIG_IGN,那么wait函数将会一直阻塞知道所有子进程终止,然后返回-1,errno设置为ECHILD.
    2)如果将ISIGCLD 配置为捕捉,那么内核立即检查是否有子进程准备好被等待,如果是这样,那么调用SIGCLD.
       但是在有些系统上SIGCLD和SIGCHLD定义是一样的。不会出现上述的行为,是一个普通信号。                                                                                                                                                                                                          
     
     
     
     
     
     
     
     
     
     
     
     
     

     

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值