Linux signal信号

信号


信号的机制:

A给B发送信号,B收到信号之前执行自己的代码,收到信号后,不管执行到程序的什么位置,都要暂停运行,去处理信号,处理完毕再继续执行。与硬件中断类似——异步模式。但信号是软件层面上实现的中断,早期常被称为“软中断”。


信号的特质:

由于信号是通过软件方法实现,其实现手段导致信号有很强的延时性。但对于用户来说,这个延迟时间非常短,不易察觉。

每个进程收到的所有信号,都是由内核负责发送的,内核处理。


信号的类型
  • SIGHUP —— 进程session leader退出时,同session的其他进程会收到这个信号

  • SIGINT —— Ctrl+C

  • SIGQUIT —— C Ctrl+D

  • SIGILL —— C 非法指令

  • SIGABRT —— C 调用abort函数产生的信号

  • SIGFPE —— C 浮点异常

  • SIGKILL —— Kill信号

  • SIGSEGV —— C 无效的内存引用

  • SIGPIPE —— 管道破裂: 写一个没有读端口的管道

  • SIGALRM —— 由alarm(2)发出的信号

  • SIGTERM —— 终止信号

  • SIGUSR1 —— 用户自定义信号1

  • SIGUSR2 —— 用户自定义信号2

  • SIGCHLD —— 子进程状态变化会给父进程发送SIGCHLD信号

  • SIGCONT —— 进程继续(曾被停止的进程)

  • SIGSTOP —— 暂停进程

  • SIGTSTP —— 控制终端(tty)上按下停止键

  • SIGTTIN —— 后台进程企图从控制终端读

  • SIGTTOU —— 后台进程企图从控制终端写

kill - l 可以查看所有信号
[1,31]信号为常规信号+不可靠信号,[34,64]称为实时信号


信号产生函数
unsigned int alarm(unsigned int seconds)
  • 指定seconds后,内核会给当前进程发送SIGALRM信号

  • 返回0或剩余的描述

每个进程有且只有一个定时器

int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value)
  • which指定定时方式,①自然定时:ITIMER_REAL -> SIGLARM信号;②虚拟空间计时: ITIMER_VIRTUAL-> SIGVTALRM信号(只计算进程占用cpu的时间);③运行时计时: ITIMER_PROF -> SIGPROF(计算占用cpu及执行系统调用的时间)

可代替alarm函数,精度微秒,可以实现周期定时


信号集操作函数
sigset_t  set;                                  //定义一个信号集
int sigemptyset(sigset_t *set);                 //将某个信号集清0  成功:0;失败:-1
int sigfillset(sigset_t *set);                  //将某个信号集置1   成功:0;失败:-1
int sigaddset(sigset_t *set, int signum);       //将某个信号加入信号集  成功:0;失败:-1
int sigdelset(sigset_t *set, int signum);       //将某个信号清出信号集  成功:0;失败:-1
int sigismember(const sigset_t *set, int signum); //判断某个信号是否在信号集中   返回值:在集合:1;不在:0;出错:-1  

sigprocmask函数

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
  • how

    1. SIG_BLOCK: 屏蔽set内信号
    2. SIG_UNBLOCK:接触屏蔽set内的信号
    3. SIG_SETMASK: 用set代替原始屏蔽
  • set 传入参数,是一个位图,32位表示前32个信号集,set中哪个位置为1则表示当前进程屏蔽哪个信号

  • oldset 传出参数,保存旧的信号屏蔽集

sigpending函数

int sigpending(sigset_t *set);

读取当前进程的未决信号集,通过set传出


信号捕捉

signal函数

void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler/*回调*/);

sigaction函数

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);  
//act: 传入参数,新的处理方式;
//oldact: 传出参数,旧的处理方式;

struct sigaction结构体

struct sigaction {
    void     (*sa_handler)(int);
    void     (*sa_sigaction)(int, siginfo_t *, void *);
    sigset_t   sa_mask; 
    int       sa_flags; 
    void     (*sa_restorer)(void);
};
  • sa_handler: 指定信号捕捉后的处理函数。可赋值SIG_IGN表示忽略,SIG_DFL表示执行默认动作

  • sa_mask: 用信号集处理函数初始化,调用sigaction函数时表示所要屏蔽的信号集合。只在处理函数被调用期间屏蔽,调用完后失效

  • sa_flags :
    SA_INTERRUPT 由此信号中断的系统调用不会自动重启
    SA_RESTART 由此信号中断的系统调用会自动重启
    SA_SIGINFO 提供附加信息,一个指向siginfo结构的指针以及一个指向进程上下文标识符的指针

  • sa_sigaction: 当sa_flags被指定为SA_SIGINFO时才使用该信号处理程序

  • sa_restorer: 弃用

sigqueue函数

int sigqueue(pid_t pid, int sig, const union sigval value);
union sigval {
           int   sival_int;    //携带int值
           void *sival_ptr;    //携带指针
       };
  • 向指定进程发送指定信号的同时,携带数据。

  • 如果传地址需注意,不同进程之间的虚拟地址空间相互独立,传递当前进程地址没有作用

pause函数

int pause(void);   //返回-1 并设置errno为EINTR
  • 如果信号默认处理终止进程,则pause没有机会返回

  • 如果信号默认处理忽略,进程继续挂起,pause不会返回

  • 如果信号默认捕捉,则正常返回

  • 如果信号pause收到的信号被屏蔽,则pause不能被唤醒

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值