博客
关于我
【Linux】进程间通信---信号
阅读量:498 次
发布时间:2019-03-07

本文共 2004 字,大约阅读时间需要 6 分钟。

信号在운算中的应用

1. 信号定义

信号是一个中断软件,它用于通知进程某种事件发生。在典型的 Embedded Unix 系统中,信号有两种形式:可靠非可靠

信号分类

  • 非可靠信号 (1~31, 33~63): 不保证按时发送,默认处理方式(SIG_DFL)。
  • 可靠信号 (34~64): 定时发送,拥有进程 ID,允许发送进程等待确认。

2. 信号的产生方式

信号可以通过 硬件软件 生成,并影响目标进程。

硬件产生的信号

  • Ctrl+C: 2号信号(SIGINT),默认终止前台进程。
  • Ctrl+Z: 20号信号(SIGTSTP),暂停前台进程。
  • Ctrl+|: 3号信号(SIGQUIT),退出当前程序。

软件产生的信号

  • kill命令: 可以发送任意信号,例如 kill -9 PID
  • abort函数: 生成 6号信号(SIGABRT),常用于抛出错误。
  • 越界或解引用: 生成 11号信号(SIGSEGV)。

3. 信号注册

信号注册是将信号映射到特定处理函数的过程。Linux 使用 sigarrays 来处理信号。

sigarray 操作流程

  • 非可靠信号:

  • 将对应位图位置设置为 1。
  • 创建 sigqueue 节点,添加至 sigqueue 队列。
  • 若队列已有节点,忽略重复操作。
  • 可靠信号:

  • 设置 sigarray 中对应位图为 1。
  • 创建 sigqueue 节点,强制添加至 sigqueue 队列(重复也会拉取)。

4. 信号注销

信号注销仅适用于非可靠信号,因为可靠信号无法回滞。

非可靠信号注销

  • 从 sigqueue 队列中移除对应 sigqueue 节点。
  • 重置 sigarray 中对应位图设置为 0。

  • 5. 信号处理

    信号处理可以是默认或者自定义处理。

    自定义处理方式

    • 使用 signal 函数定义处理函数:
      typedef void (*sighandler_t)(int);int signal(int signum, sighandler_t handler);

      例如:

      signal(2, sigback); // 处理 2号信号

    6. sigaction 函数

    sigaction 函数允许更复杂的处理逻辑。

    sigaction 结构

    struct sigaction {    void (*sa_handler)(int);    // 处理函数指针    void (*sa_sigaction)(int, siginfo_t *, void*); // 复杂处理    sigset_t sa_mask;        // collector mask    int sa_flags;            // SA_* 标记    void (*sa_restorer)(void); // 恢复函数};

    使用示例

    void sigback(int signo) { printf("signo: %d\n", signo); }int main() {    struct sigaction act;    act.sa_flags = SA_SIGINFO; // 设置处理方式为 sigaction 函数    act.sa_handler = sigback;    sigaction(2, &act, NULL);    while (1) {        printf("linux so easy!\n");        sleep(1);    }    return 0;}

    7. 信号捕捉流程

    信号捕捉发生在:

  • 进程进入内核空间。
  • 调用 do_signal 函数处理信号。
  • 具体步骤

  • 进入内核空间: 调用系统调用函数或库函数。
  • 处理信号: 调用 do_signal
  • 执行信号处理函数:
    • 使用 sa_handlersa_sigaction 根据 sa_flags 调用相应函数。

  • 8. 信号阻塞

    信号阻塞允许进程暂时不响应特定信号。

    使用方法

  • 调用 sigprocmask 函数设置 sig_setsig_unblock 操作模式。
  • 示例:
  • #include 
    #include
    int main() { sigset_t mask; sigset_t old_mask; sigempty(mask); // 初始化阻塞位图 sigprocmask(SIG_BLOCK, &mask, &old_mask); // 之后可以根据需求调用 sig_unblock 或 sig_setmask sleep(1); return 0;}

    通过以上方法,可以更好地管理和处理信号,在嵌入式开发中实现高效 middlewares。

    转载地址:http://lnacz.baihongyu.com/

    你可能感兴趣的文章
    Python IO编程
    查看>>
    使用 TortoiseGit 时,报 Access denied 错误
    查看>>
    基于 HTML5 WebGL 的污水处理厂泵站自控系统
    查看>>
    c++之程序流程控制
    查看>>
    李笑来必读书籍整理
    查看>>
    Hadoop(十六)之使用Combiner优化MapReduce
    查看>>
    《机器学习Python实现_10_06_集成学习_boosting_gbdt分类实现》
    查看>>
    C语言编译错误列表
    查看>>
    看明白这两种情况,才敢说自己懂跨链! | 喵懂区块链24期
    查看>>
    CentOS5 Linux编译PHP 报 mysql configure failed 错误解决办法
    查看>>
    python中列表 元组 字典 集合的区别
    查看>>
    Android DEX加固方案与原理
    查看>>
    iOS_Runtime3_动态添加方法
    查看>>
    Problem G. The Stones Game【取石子博弈 & 思维】
    查看>>
    Java多线程
    查看>>
    openssl服务器证书操作
    查看>>
    我用wxPython搭建GUI量化系统之最小架构的运行
    查看>>
    selenium+python之切换窗口
    查看>>
    重载和重写的区别:
    查看>>
    搭建Vue项目步骤
    查看>>