zoukankan      html  css  js  c++  java
  • LinuxC信号-进程间通信方式之一

    1.信号特性:
      简单但不可靠,不能携带大量信息,特定条件才触发。
      包括软件中断和硬件中断。
        软件中断如:调用abort、raise,alarm,setitimer等函数触发的中断
        硬件中断如:除0导致的SIGFPE(浮点数例外),非法访问内容导致的SIGSEGV(段错误),非法内容对齐等导致的总线错误(SIGBUS) 等等

    2.信号三要素:
      1)编号:信号编号范围是1~64。1~31为常规信号编号。34-64为实时信号。
      2)事件:同时每个编号对应一个触发事件。如1->SIGHUP,2->SIGINT,3->SIGQUIT,... man 7 signal 可查看全部信号。
           常见对应事件:Ctr+c 产生SIGINT(2),Ctrl+ 产生SIGQUIT(3),Ctrl+z 产生SIGTSTP(20),
           除0操作 产生SIGFPE(8)浮点数例外,非法访问内存 产生SIGSEGV(11)段错误,非法内存对齐等 产生SIGBUS(7)总线错误
      3)默认动作:包括 Term终止进程,Ign忽悠,Core终止进程并生成Core文件,Stop暂停进程,Cont继续进行。
            注意:SIGKILL(9)和SIGSTOP(19)信号不允许被屏蔽、忽略、捕捉等,只能执行默认动作。SIGKILL默认终止进程,SIGSTOP默认暂停进程。

    3.常见信号产生函数
      kill(pid,sig)函数:发送sig信号。pid>0给指定进程 发送sig信号,pid=0给同组进程 发送sig信号,pid<-1给指定进程组 发送sig信号,pid=-1给所有进程 发送sig信号。
      raise(sig) 函数:给当前进程发送sig信号。
      abort() 函数:给当前进程发送SIGABRT信号。
      alarm(sec) 函数:sec大于0时表示sec秒后给当前进程发送SIGALRM信号。sec=0表示取消定时器。每个进程只有唯一一个定时器。
      setitimer() 函数:周期定时器,which可选:ITIMER_REAL(自然定时,产生SIGALRM信号)、ITIMER_VIRTUAL(虚拟用户空间计时,产生SIGVTALRM信号)、ITIMER_PROF(运行时计时,产生SIGPROF信号)
              
    4.信号集
      未决信号集:产生了但还没决定处理的待处理信号集合。未决就是没决定的意思嘛。
      阻塞信号集:一般称为信号屏蔽字mask。用来告诉内核屏蔽哪些信号,也就是说告诉内核哪些信号屏蔽掉不处理。
      内核是通过读取未决信号集来判断信号是否应该被处理的,信号屏蔽字mask可以影响未决信号集合。我们可以通过程序修改mask的值达到屏蔽指定信号的目的。
      简单理解:就是所有未处理的信号,经过信号屏蔽字筛选后,剩下的就是未决信号集.

    5.常见信号集操作函数
      sigset_t:信号集类型,是一个unsigned long类型。没错,是一个基本数据类型,但表示一个信号集合,说明是按位操作。
      sigemptyset(sigset_t *set)    函数:将set集合按位清空为0
      sigfillset(sigset_t *set)     函数:将set集合按位填充为1
      sigaddset(sigset_t *set,signum) 函数:将signum信号添加到set集合
      sigdelset(sigset_t *set,signum) 函数:将signum信号从set集合删除
      sigismember(sigset_t,signum)   函数:判断signum信号是否在set集合里
        注意:sigaddset()、sigdelset()、sigismember()等函数调用之前必须先调用sigemptyset()或者sigfillset()函数初始化信号集。
      sigprocmask(int how,sigset_t *set,sigset_t *oldset)    函数:用来屏蔽、解除屏蔽某个信号,本质是读取并修改PCB(在进程内核里)里的信号屏蔽字mask。
        how:为SIG_BLOCK时,set表示需要屏蔽的信号,相当于mask=mask|set,"或"操作
           为SIG_UNBLOCK时,set表示需要解除的信号,相当于mask=mask&~set,"取反"后再"与"操作
           为SIG_SETMASK时,set表示用于替换之前的信号屏蔽字,相当于mask=set,set成为新的信号屏蔽字。
        set:传入参数,需要操作的信号集
        oldset:传出参数,返回之前的信号集额,一般用于恢复时使用。
      sigpending(sigset_t *set):    函数:读取当前进程的未决信号集,set为传出参数。
      pause()  函数:主动挂起,处于阻塞状态,等等任一信号送达唤醒,该信号不能是被屏蔽的,不然没法送达呀。
      sigsuspend  函数:挂起等待信号。类似于pause函数,但pause有时序问题,可以使用sigsuspend函数解决时序问题。
      sigqueue  函数:对应kill函数,信号传参,携带union参数。传递指针的话,本进程内才有意义。因为每个进程都有自己独立的空间,进程间传递指针是没有意义的。
      
    6.信号捕捉函数
      signal(signum,handler)函数:
        捕捉指定的signum信号,触发回调handler函数。handler是一个函数指针。由于历史原因,兼容性较差,很少使用。
      sigaction(signum,struct sigaction *act,struct sigaction *oldact)函数
        捕捉指定的signum信号,回调函数再act结构体里。act为传入参数,新的处理方式。oldact为传出参数,返回旧的处理方式,一般用于之前恢复处理方式时使用。
        struct sigaction{
          void (*sa_handler)(int);//信号捕捉后的处理函数,也可以指定为SIG_IGN表示忽悠,SIG_DEL表示默认处理方式
          void (*sa_sigaction)(int,siginfo_t*,void*);//sa_flags指定为SA_SIGINFO时信号捕捉后改为调用该函数,不调用sa_handler函数
          sigset_t sa_mask;//处理函数执行期间(可能执行很长时间呀)的信号屏蔽字,表示处理函数执行期间屏蔽哪些信号
          int sa_flags;//特定标识位,通常为0表示默认属性
          void (*sa_restorer)(void);//已过时,已弃用
        }
        处理函数执行期间,屏蔽字由sa_mask指定,默认情况下处理函数执行期间,被捕捉信号自动屏蔽,常规信号不支持排队,多次产生同一信号可能只产生一次触发

    7.SIGCHLD信号
      子进程终止时,或者子进程收到SIGSTOP信号暂停时,或者子进程收到SIGCONT信号后继续运行时,都会发送该信号。

      


  • 相关阅读:
    CSS媒体查询
    搜索关键词标注红色
    揭秘 | 小白如何0基础0元建站
    细说浏览器输入URL后发生了什么
    js问题总结
    vue elementui如何修改el-table头部样式
    h5开发微信公众号重定向到关注页面没有关注按钮 (微信你个坑)
    下拉展开动画
    html中常用的转义字符总结
    9个设计师常用的高清图库 不敢配图? 这9个免版权图库牢记心中!
  • 原文地址:https://www.cnblogs.com/yongfengnice/p/11953839.html
Copyright © 2011-2022 走看看