Linux系统——信号

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_40797414/article/details/82261416
  1. 信号的基本概念
    为了理解信号,先从我们最熟悉的场景说起。
    用户输入命令,在shell下启动一个前台进程。
    用户按下ctrl+c,这个键盘输入产生一个硬件中断。
    如果CPU当前正在执行这个进程的代码,则该进程的用户空间代码暂停执行,CPU从用户态切换到内核态处理硬件中断。
    中断驱动程序将Ctrl -c解释成一个SIGINT信号,记在该进程的PCB中(也可以说发送了一个SIGINT信号给该进程 ) 。
    当某个时刻要从内核返回到该进程的用户空间代码继续执行之前,首先处理PCB中记录的信号,发现有一个SIGINT信号待处理,而这个信号的默认处理动作是终止进程,所以直接终止进程而不再返回它的用户空间代码执行。
    注意:Ctrl-c产生的信号只能发给前台进程。一个命令后面加个&可以放到后台运行,这样Shell不必等待进程结束就可以接受新的命令,启动新的进程。
    Shell可以同时运行一个前台进程和任意多个后台进程,只有前台进程才能接到像ctrl_c这种控制键产生的信号。
    前台进程在运行过程中用户随时可能按下ctrl-c而产生一个信号,也就是说该进程的用户空间代码执行到任何地方都有可能收到SIGINT信号而终止,所以信号相对于进程的控制流程来说是异步3的。
    kill -l:查看系统定义的信号列表。
    产生信号的方式:
    (1)用户在终端按下某些键时,终端驱动程序会发送信号给前台进程,如ctrl-c产生SIGINT信号,ctrl-\产生SIGQUIT信号,ctrl-z产生SIGTSTP信号(可使前台进程停止)
    (2)硬件异常产生信号,这些条件由硬件检测到并通知内核,然后内核向当前进程发送适当的信号,
    (3)一个进程调用kill(2)函数可以发送信号给另一个进程。可以用kill(1)命令发送 信号给某个进程,kill(1)命令也是调用kill(2)函数实现的,如果不明确指定信号则发送SIGTERM信号,该信号的默认处理动作是终止进程。当内核检测到某种软件条件发生时也可以通过信号通知进程,例如闹钟超时产生SIGALRM信号,向读端已关闭的管道写数据时产生SIGPIPE信号。如果不想按默认动作处理信号,用户程序可以调用sigaction(2)函数告诉内核如何处理某中信号。
    (4)软条件产生。
    信号处理常见方式概览:(1)忽略此信号(2)执行该信号的默认处理动作。
    (3)提供一个信号处理函数,要求内核在处理该信号时切换到用户态执行这个处理函数,这种方式称为捕捉一个信号。
    产生信号
    (1)通过终端按键产生信号
    SIGINT的默认处理动作是终止进程,SIGQUIT的默认处理动作是终止进程并且Core Dump。
    Core Dump:当一个进程要异常终止时,可以选择把进程的用户空间内存数据全部保存到磁盘上,文件名通常是core,这叫做Core Dump.进程异常终止通常是因为有Bug,比如非法内存访问导致段错误,事后可以用调试器检查core文件以查清错误原因,这叫做Post-mortem Debug(事后调试)
    一个进程允许产生多大的Core文件取决于进程的Resource Limit(这个信息保存在PCB中)。默认是不允许产生core文件的,因为core文件中可能包含用户密码等敏感信息,不安全。在开发调试阶段可以用ulimit命令改变这个限制,允许产生core文件。首先用ulimit命令改变shell进程的Resource Limit,允许core文件最大为1024k: ulimit -c 1024.
    kill命令是调用kill函数实现的。kill函数可以给一个指定的进程发送指定的信号。raise函数可以给当前进程发送指定的信号。
    int raise(int signo)
    这两个进程都是成功返回0,错误返回-1。
    #include

猜你喜欢

转载自blog.csdn.net/weixin_40797414/article/details/82261416
今日推荐