进程信号

信号源

1、硬件
2、软件

查看系统有哪些信号

kill -l

进程收到信号的三种响应:

1、忽略信号 不能忽略 SIGKILL、SIGSTOP
2、捕获并处理 (自定义) 不能捕获 SIGKILL、SIGSTOP
3、缺省处理 缺省处理到底执行什么动作,详见 man 7 signal

安装信号(注册信号)

void(*signal(int  signo,  void  (*handler)(int)) )(int);
//从左到右找第一个不是关键字的
//参数:signo  要注册的信号 handler  信号处理函数

  /*
    define  SIG_IGN((sighandler_t*)(1))   :忽略
    define  SIG_DFL((sighandler_t*)(0))   :缺省
    define SIG_ERR((sighandler_t*)(-1))   :返回错误
  */
//signal(SIGIN, SIG_IGN)
//返回值: 旧的信号处理

信号分类

1、可靠信号和不可靠信号
不可靠表现在:
1)当执行完信号处理函数后,恢复成缺省处理动作
2) 当多个信号同时抵达,可能出现信号丢失
1-31 :不可靠
34-64: 可靠

2、实时信号和非实时信号
实时信号都是可靠信号
非实时信号都是不可靠信号

发送信号(kill 命令)

int  kill(pid_t pid,  // 给那个进程发送信号
         int signal);  // 发送什么信号
/*pid  :
   >0   发送给指定的进程
   =0   发送本进程组任何一个信号
   =-1  发送给本进程有权发送的任何一个进程
   <-1  发送给|pid|进程组的任何一个进程
*/

SIGALRM

   int  alarm(int set);
        //set : 过了set这么多秒,信号SIGALRM抵达
       // 0 清除

setitimer函数

setitimer( int which,   const  struct itimerrval *val, struct timeval *old); //定时器
//which :ITIMER_REAL
/*struct itimerval {
               struct timeval it_interval; /* next value */       //以后每次间隔时间
               struct timeval it_value;    /* current value */   //第一次启动时间
           };
 */
/* struct timeval {
               time_t      tv_sec;         /* seconds */  秒
               suseconds_t tv_usec;        /* microseconds */  微秒
           };
  */

超时问题

SIGCHLD 当子进程变成僵尸进程,系统会给父进程发送这个信号
signal(SIGCHLD,STG_IGN);// SIGCHLD 缺省是忽略,但不会将僵尸进程处理掉,我们将捕获并告诉系统SIG_IGN ,子进程死亡,不会出现僵尸

可重入和不可重入函数

如果函数内部:

  1. 操纵静态变量
  2. 调用了malloc/free,因为malloc使用全局链表来管理的
  3. 使用标准IO

就是不可重入函数

可重入函数:可以被任意打断

信号的内核表示

递达:执行信号处理动作称为信号的递达(delivery)
从信号的产生到信号的递达之间的状态称为未决(pending)
进程可以阻塞(block)信号,被阻塞信号产生时,一直处于未决状态,直到该进程解除对该信号的阻塞,才执行该动作。

 //清空信号集
int sigemptyset(sigset_t  *set);                         
//填充
int sigfillset(sigset *set);
//将某一个信号加入信号集
int sigaddset(sigset _t*set, int signum);
//将某一信号从信号集中删除
int sigdeiset(sigset _t*set, int signum);
//判断某一个信号是否在信号集中
int sigismember(const sigset_t *set, int signum)

sigprocmask 信号阻塞(信号屏蔽)

int sigprocmask(int how, const sigset_t *set  , sigset_t *old);
/*how :
SIG_BLOCK :     mask =mask|(*set)
SIG_UNBLOCK: mask=mask&(~set)
SIG_SETMASK:  mask =*set
*/
//返回值:成功为0,出错为1

获取信号内核的未决状态集

int  sigpenfding(sigset_t *t)

竞态 : 跟时间有关的错误

int  pause(void); //将当前进程挂起,转存储调度,直到有信号抵达,才唤醒该进程
for(; ;)
    pause();
int sleep()
{
}
int signsuspend(const sigset_t *set);
//等价于pause+信号屏蔽

int sigaction(int signo,  
              struct signaction *set,  //设置信号处理
              struct signaction *old) //返回旧的信号处理

/*struct sigaction {
               void     (*sa_handler)(int);
               sigset_t   sa_mask;   //信号处理函数执行期间的信号屏蔽
               int        sa_flags; // 0
           };
  */
//volatile : 保持内存可见性

相关代码

这里写代码片
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值