unix 环境高级编程 信号函数杂记一

kill函数:

      函数原型:int   kill(pid_t pid,int signo);

      函数返回值:成功则返回0,不成功则返回-1.

      函数作用:向进程pid传递signo信号

      详细的参数pid的限制见apueP251。

      需要注意的地方:如果调用kill函数为调用者进程产生信号(也就是自己向自己传递信号,相当于raise),而且此信号是不被阻塞的,那么在kill返回之前,就会将signo信号或者是

某个其他未决的非阻塞信号传递给该进程(也就是调用信号处理动作,递达),利用kill函数的这个特性apue上面实现了很多的函数,比如:p275页的abort函数,以及p283的10-22

alarm函数:     

      函数原型: int   alarm(unsigned int sec);

      函数的返回值: 0或者是剩余的响铃时间秒数

      内核产生的信号为:SIGALRM,默认动作是终止进程

      注意的地方:每个进程仅能有一个闹铃时钟,如果在一个进程中设置了两个闹铃时钟,会发生覆盖重置现象,另外需要注意的地方是:SIGALRM信号的处理函数要在alarm函数之前,这是因为写在之后,不保证该signal函数执行时SIGARM信号已经递达,原因有很多,比如说系统繁忙,使得在执行完alarm(sec)之后,下次执行是在sec秒之后的某个时刻,则这个时候内核产生SIGALRM信号,会采用信号的默认处理程序,也就是终止进程。

pause函数:

    函数原型:int pause(void)

    函数返回值:-1,并且将erron设置为EINTR

   函数作用:进程挂起直到捕捉到一个信号.注意这里是捕捉

   注意:

           如果信号的处理动作是终止进程,则进程终止,pause函数没有机会返回

           如果信号的处理动作是忽略,则pause()无法返回,进程仍挂起

           有相应的信号处理函数,pause函数才有可能返回,注意这里是有可能返回,原因在于可能在信号处理完之后,pause函数才执行,例如apue上的p253的sleep1函数

sigpromask函数:

      函数原型:int  sigpromask(int how,const sigset_t * restrict  set,const sigset_t* restrict oset);

      函数作用:检测或者是设置信号屏蔽字signal mask

      函数参数:set:指向将要处理的信号屏蔽字,oset返回当前设置的信号屏蔽字,也就是在调用sigpromask之前的信号屏蔽字,

                         how:  SIG_BLOCK:用于将当前的信号屏蔽字加上set所指向的信号屏蔽字,也就是求两者的并集作为新的信号屏蔽字

                                   SIG_UNBLOCK:当前信号屏蔽字与set所指向的信号屏蔽字的差集,set中指向的是我们想解除阻塞的信号

                                    SIG_SETMASK:赋值操作,将set完全代替当前的信号屏蔽字成为新的信号屏蔽字

     函数返回值:成功则返回0,否则返回-1

    注意的地方:在调用sigpromask后如果有任何未决的。不再阻塞的信号。则在sigpromask函数返回之前,至少会将其中的一个信号传递给该进程,这点和kill函数很相似。

    如果想要得到当前的信号屏蔽字,可以这样:sigpromask(0,NULL,&sigset),其中sigset是sigset_t类型的变量

sigaction函数:

     函数原型:int   sigaction(int signo,const struct  sigaction* retrict act,const struct sigaction* restrict  oact);

     函数作用:检查或者是指定与相关信号特定的处理动作

     函数参数:signo是要处理的信号,结构体sigaction包含下述的信息:

                          {

                                     void (*sa_handler)(int) ;//信号处理函数

                                     sigset_t  sa_mask;//sigaction函数执行期信号屏蔽字

                                     int  sa_flags;//信号处理选项

                                     void (*sa_sigaction)(int ,siginfo_t *,void*);//可选的信号处理函数

                        }         

                        第三个参数为当前设置值

    注意的地方:sa_mask是一个信号集,在调用信号处理函数之前,将其加到信号的屏蔽字当中去,仅当从信号处理函数返回之后再将信号的屏蔽字复位为原来的值.这样在调用信号处理函数时就可以阻塞某些信号,其中包括sigaction函数处理的信号。极端情况下,阻塞所有的除本信号之外的所有的信号,这样sigaction函数将不会被中断,在apue上10-22有这个应用,就是这么干的。  一旦对给定的信号设置了一个动作,那么在调用sigaction显示的改变之前,该设置将一直有效,也就是说不会存在在处理完一个信号之后下一个相同的信号的处理改为系统默认的情况。 当在sa_flags中 使用了SA_SIGINFO标志的时候,会调用sa_sigaction处理函数,该函数包含比较详尽的信息,其中的siginfo包含了信号产生原因的信息。context包含了进程的上下文信息。

 sigsetjmp与siglongjmp函数:

                   函数原型:int  sigsetjmp(sigjmp_buf  env,int  savemask);

                                       int   siglongjmp(sigjmp_buf  env,int val);

                   函数作用:信号处理程序中的非局部性转移函数

                   函数参数:env:保存进程当前的环境,用于siglongjmp的转移时恢复环境,savemask:保存进程当前的信号屏蔽字,用于siglongjmp返回时复位用的,val设置sigsetjmp的返回值。

     注意的地方:这两个函数与setjmp,longjmp不同的地方在于当捕捉到一个信号进入信号处理函数之后,此时当前信号被自动的加到进程的信号屏蔽字当中,这阻止了后来相同的信号中断信号处理函数,但是如果使用longjmp跳离信号处理函数之后,该信号的对应的信号屏蔽字会怎么样呢?是被复位还是继续阻塞?对于这个问题,不同的unix系列有不同的设计方案。为了解决这个问题,才有了上述的两个转移函数,这两个函数的语义很明确,在信号处理函数中,该信号被自动的加到进程的信号屏蔽字当中,但是在调用siglongjmp返回时,会进行复位。apue上的10-14很好的说明了这一点                                     


 


                     



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值