信号实际上就是软件层面模拟中断的一种方式,也称为软中断。
typedef void (*sighandler_t)(int s);
sighandler_t signal(int signum, sighandler_t handler);
注册信号处理函数,
标准信号1~31,实时信号34~64
标准信号中SIGCONT,SIGSTOP,SIGSEGV,SIGINT(ctrl + c),SIGALRM,SIGQUIT(ctrl + \)
标准信号又五种默认行为:
Term:进程终止。
Stop:进程停止等待。
Cont:进程继续执行。
Ign:进程忽略信号
Core:进程终止并产生dump文件
进程接收到标准信号有三种行为:
执行默认行为
选择屏蔽掉,忽略信号
响应这个信号的信号处理函数
fork和信号:
fork创建的子进程集成父进程的信号的行为和信号的屏蔽,
如果子进程进行了替换,信号的行为会重新设置为默认行为。
信号响应的过程:
内核为信号维系了两个位图:mask和pendding
mask:置1代表信号被屏蔽,置0代表不被屏蔽,默认为0。
pendding:置1代表信号产生了,置0代表了信号没有产生,默认为0。
main函数接收到信号之后,进入内核态,内核判断pendding & ~mask是否为1,为1的话讲pendding位置0,mask位置1,然后返回用户态执行信号处理函数,函数执行结束后,将mask位置0。
异步:什么时候产生是不确定的,产生什么样的后果也是不确定的。
信号是典型的初步异步事件。
捕获异步事件的方法:
轮询法:一直查询,适用于密集型事件
通知法:不用查询,等待通知。
流量控制:
漏桶:
流入的速率不恒定,流出的速率是恒定的。
不容易调整容量的限制。
适合突发性的高并发,例如整点支付,秒杀活动。
保护服务器自己。
令牌桶:
一定的速率积攒令牌,令牌的数量是有上限的。
请求服务是可以解决突发事件的,请求响应的令牌个数就行,如果令牌数量不能满足,则丢弃。
处理本身的流量控制同时还可以保护第三方服务。
更适合处理突发的事件。
令牌的三要素:速率,令牌当前个数,上限