Linux Signals 进程信号简介

在Linux中,signal是一种局限较强的进程间通信方式。

主要有三种类型:

1. 从hardware signal到POSIX signal

    hardware signal也叫hardware interrupt,CPU中存放着 interrupt vectors 指向 存放在kernel space中的interrupt handling routine。

    例: 键盘输入;segmentation fault -> SIGSEGV 

2. 直接从kernel生成的POSIX signal

    例:exit() -> SIGCHLD

3. 从一个进程发起到另一个进程的signal

    例:进程885 执行了 “kill 1234” 代码

 

POSIX signal

1. Generated from CPU to kernel, or from CPU to processes

    例 1: Segmentation fault.
        The signal is labeled SIGSEGV, which comes from CPU to kernel then to process.
    例 2: Floating point exception (e.g., divided by 0).
        The signal is labeled SIGFPE, which is coming from CPU to process

2. From kernel to process

    例: Child process termination.
        The signal is labeled SIGCHLD, which is coming from the kernel to process

3. Generated from one process to another

    例: From terminals: E.g., “Ctrl C”, “Ctrl Z”
            Using programs: E.g., “kill”, “top”, etc.
            Using the “kill()” system call.

 

一些典型的signal

183355_dDcG_2242731.png

 

Asynchronous signal: 异步信号
– The signal received is NOT generated by the process itself。 So, its arrival time is usually not deterministic
– E.g., External hardware interrupt, another process sends ctrl-c


Synchronous signal: 同步信号
– The signal is caused by the process itself, its arrival time is usually deterministic
– E.g., A certain line leads to SIGFPE 
– E.g., A certain line accesses a memory region: SIGSEGV

 

kill() 方法

用于给特地进程发送POSIX signal

212721_GtoH_2242731.png

 

signal() 方法

更新当前进程的特定signal的处理方法,即signal handler

212942_vZQG_2242731.png

例:写个无法“Ctrl+C”中止的小病毒

#include <stdio.h>
#include <signal.h>

void sig_handler(int sig) {
  if(sig == SIGINT)
    printf("\nCtrl + C\n");
}

 int main(void) {
     signal(SIGINT, sig_handler);
     printf("Press enter\n");
     getchar();
     printf("End of program\n");
     return 0;
}

 

通常情况下,我们希望当signal handler处理完signal后,程序恢复到之前执行的地方;而有时候,则希望程序继续运行下去。

214032_e1J1_2242731.png

 

signal的检查方法

一个进程如何知道它收到了一个特定的signal?

在kernel space中,有一个bitmask

215141_LsjV_2242731.png

进程会不定期地去检查这个bitmask,如果看到是1,则调用对应的handler,并重置为0。

因此,发送signal和处理signal是异步的。

 

pause()方法

The pause() system call suspends the calling process until a signal is received. 等待一个信号

 

有益的重写signal handler

重写SIGINT的handler,保证进程在被用户ctrl-c 中止之前,进行一些必要的清理工作比如 关闭数据库连接等。

 

alarm()方法

设置一个“闹钟”在指定时间后“响”起。

通过在hardware设置一个闹钟,到达时间后,hardware的signal会转换成SIGALRM signal发送给进程,默认的处理方式是结束当前进程。

alarm()是一次性的,如果需要周期性的,则使用 settimer()方法

 

 

转载于:https://my.oschina.net/Bruce370/blog/885260

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值