• 三十、Linux 进程与信号——信号的概念及 signal 函数


    30.1 信号的基本概念

    • 信号(signal)机制是Linux 系统中最为古老的进程之间的通信机制,解决进程在正常运行过程中被中断的问题,导致进程的处理流程会发生变化
    • 信号是软件中断
    • 信号是异步事件
      •   不可预见
      • 信号有自己的名称和编号
      • 信号和异常处理机制
    • 信号发生的来源
      • 硬件来源:如按下键盘或其他硬件故障,信号是由驱动程序产生
      • 软件来源:最常用发送信号的系统函数是 kill(),raise(),alarm() 和 setitimer() 等函数,软件来源还包括一些非法运算等操作,软件设置条件(如:gdb调试),信号是由内核产生。

      查看系统当中的信号:kill -l

      

    • [1 ~ 31] 信号称为非实时信号
      • 发送的信号可能丢失,不支持信号排队
    • [32 ~ 64] 信号称为实时信号
      • 发送的多个实时信号都会被接受,支持信号排队
    • 信号无优先  信号定义的地方:/usr/include/bits/signum.h 和 signum-generic.h

    30.2 信号的处理和变革

    30.2.1 信号的处理

    • 忽略信号
      • SIGKILL 和 SIGSTOP 永远不能忽略
      • 忽略硬件异常
      • 进程启动时 SIGUSR1 和 SIGUSR2 两个信号被忽略
    • 执行默认操作
      • 每个信号有默认动作,大部分信号默认动作是终止进程
    • 捕获信号
      • 告诉内核出现信号时调用自己的处理函数
      • SIGKILL 和 SIGSTOP 不能被捕获

    30.2.2 信号变革

    • 信号出现在早期的 UNIX 中
    • 早期信号模型是不可靠的
    • BSD 和 SYSTEM V 分别对早期信号进行扩展,但是相互不兼容
    • POSIX 统一了上述两种模型,提供了可靠信号模型  

    30.3 signal 函数

    1 #include <signal.h>
    2 void (*signal(int signo, void (*func)(int )))(int );
    • 函数功能:向内核登记信号处理函数
    • 函数参数:
      • signo:要登记的信号值
      • func:
        • 信号处理函数指针
        • SIG_IGN:忽略信号
        • SIG_DFL:采用系统默认的方式处理信号,执行默认操作
    • 返回值:若成功,则返回先前的信号处理函数指针,出错,则返回 SIG_ERR 

      signal 函数原型如下:

      

      

     1 #include <signal.h>
     2 #include <stdlib.h>
     3 #include <stdio.h>
     4 #include <unistd.h>
     5 
     6 /** 定义信号处理函数
     7  *  signo   进程捕获到的信号
     8  */
     9 void sig_handler(int signo)
    10 {
    11     printf("%d, %d occured
    ", getpid(), signo);
    12 }
    13 
    14 int main(void)
    15 {
    16     /** 向内核登记信号处理函数以及信号值 */
    17     if(signal(SIGTSTP, sig_handler) == SIG_ERR) {
    18         perror("signal sigtstp error");
    19     }
    20 
    21     if(signal(SIGINT, sig_handler) == SIG_ERR) {
    22         perror("signal sigint error");
    23     }
    24 
    25     if(signal(SIGUSR1, sig_handler) == SIG_ERR) {
    26         perror("signal usr1 error");
    27     }
    28 
    29     if(signal(SIGUSR2, sig_handler) == SIG_ERR) {
    30         perror("signal usr2 error");
    31     }
    32 
    33     if(signal(SIGKILL, SIG_IGN) == SIG_ERR) {
    34         perror("signal sigtstp error");
    35     }
    36 
    37     if(signal(SIGSTOP, SIG_IGN) == SIG_ERR) {
    38         perror("signal sigint error");
    39     }
    40     int i = 0;
    41     while(i < 30) {
    42         printf("%d out %d
    ", getpid(), i++);
    43         sleep(50);
    44     }
    45 
    46     return 0;
    47 }

     

  • 相关阅读:
    蓝牙搜索
    Log4cpp介绍及使用
    单独卸载vs2010帮助文档HelpView之后的独立安装教程
    C++Builder RAD Studio XE, UTF-8 String 转换为 char * 字符串的最简单方式, 常用于sqlite3开发
    vs2012 MSDN帮助文档离线包下载安装方法
    关于OBJ/LIB格式,我以前有个总结
    关于C++ const 的全面总结
    在 C++Builder 工程里调用 DLL 函数
    c++builder调用VC的dll以及VC调用c++builder的dll
    C++Builder及VC的库相互调用
  • 原文地址:https://www.cnblogs.com/kele-dad/p/10115704.html
Copyright © 2020-2023  润新知