当前位置: 首页 > news >正文

网站建设公司企业网站管理系统云盘网页版登录

网站建设公司企业网站管理系统,云盘网页版登录,镇江百度网站建设,企业网站只用静态页目录 0.前言 1. 通过终端按键产生信号 1.1 CtrlC:发送 SIGINT 信号 1.2 Ctrl\:发送 SIGQUIT 信号 1.3 CtrlZ:发送 SIGTSTP 信号 2.调用系统命令向进程发信号 3.使用函数产生信号 3.1 kill 函数 3.2 raise 函数 3.3 abort 函数 4.由软件条件产…

目录

0.前言

1. 通过终端按键产生信号

1.1 Ctrl+C:发送 SIGINT 信号

1.2 Ctrl+\:发送 SIGQUIT 信号

1.3 Ctrl+Z:发送 SIGTSTP 信号

2.调用系统命令向进程发信号

3.使用函数产生信号

3.1 kill 函数

3.2 raise 函数

3.3 abort 函数

4.由软件条件产生信号

4.1 SIGPIPE 信号

4.2 SIGALRM 信号

5.硬件异常产生信号

5.1 常见硬件异常信号

5.1.1 除 0 操作:SIGFPE 信号

5.1.2 访问野指针:SIGSEGV 信号

5.2 核心转储(Core Dump)

6.小结


(图像由AI生成) 

0.前言

在 Linux 系统中,信号是用于进程间通信的重要机制,通过信号可以实现对进程的控制、状态传递以及异常处理。在上一篇博客中,我们简单介绍了进程信号的概念、常见类型以及信号的基本作用。本篇博客将继续深入,从信号的产生开始,探讨信号如何被触发并送达进程。这是理解信号处理的第一步,也是后续学习信号保存和信号处理机制的基础。通过本篇内容,你将了解信号的几种常见触发方式,包括用户手动产生、程序主动触发,以及系统自动生成等场景。

1. 通过终端按键产生信号

Linux 系统中,终端不仅是与操作系统交互的重要工具,也是信号产生的主要入口之一。在终端中按下特定的键盘组合,可以向当前前台进程发送信号,这些信号可以中断、暂停或终止程序运行。

1.1 Ctrl+C:发送 SIGINT 信号

  • 概念
    按下 Ctrl+C 会向当前前台进程发送 SIGINT 信号(Signal Interrupt)。这是用户最常用的中断方式,用于优雅地终止正在运行的程序。

  • 默认行为
    程序收到 SIGINT 信号后,默认会立即终止执行,但不会生成核心转储文件。

  • 实际场景
    例如,当你运行一个死循环脚本时,可以通过 Ctrl+C 终止它:

    while true; do echo "Running..."; sleep 1; done

    按下 Ctrl+C 后,循环将中止。

  • 自定义处理
    程序也可以捕获 SIGINT 信号并定义自定义逻辑。例如,以下代码展示了如何拦截并处理 SIGINT 信号:

    #include <stdio.h>
    #include <signal.h>void handle_sigint(int sig) {printf("Caught SIGINT signal: %d\n", sig);
    }int main() {signal(SIGINT, handle_sigint);while (1) {printf("Running... Press Ctrl+C to interrupt\n");sleep(1);}return 0;
    }
    

1.2 Ctrl+\:发送 SIGQUIT 信号

  • 概念
    按下 Ctrl+\ 会触发 SIGQUIT 信号(Signal Quit)。与 SIGINT 类似,SIGQUIT 的默认行为也是终止进程,但它会额外生成一个核心转储文件(core dump)。

  • 默认行为
    程序收到 SIGQUIT 信号后,系统会记录程序运行时的内存状态,生成 core dump 文件,供开发者调试使用。

  • 实际场景
    在程序运行时按下 Ctrl+\,程序不仅会终止,还会留下 core dump 文件。如果 core dump 未启用,可以通过以下命令启用:

    ulimit -c unlimited # 设置核心文件大小为无限

1.3 Ctrl+Z:发送 SIGTSTP 信号

  • 概念
    按下 Ctrl+Z 会向前台进程发送 SIGTSTP 信号(Signal Terminal Stop)。该信号用于将进程挂起(暂停运行),并将控制权还给终端。

  • 默认行为
    收到 SIGTSTP 信号后,进程会进入“暂停”状态,直到用户手动恢复它。恢复命令包括:

    • fg:恢复进程到前台继续执行。
    • bg:将进程移至后台继续执行。
  • 实际场景
    当运行一个耗时较长的任务时,可以按 Ctrl+Z 暂时挂起它,进行其他操作。例如:

    sleep 100

    按下 Ctrl+Z 后,任务将暂停。输入 fg 恢复它,或者使用 bg 将其移至后台。

2.调用系统命令向进程发信号

在 Linux 系统中,除了通过终端按键,用户还可以使用系统命令向进程发送信号。其中最常用的命令是 kill,它允许用户直接向目标进程发送指定信号,以控制或终止进程。kill 命令的基本语法如下:

kill [选项] <进程ID>

常用选项

  • -SIGNAL:指定发送的信号名称或编号。例如,-SIGKILL-9 表示发送 SIGKILL 信号。
  • -l:列出所有信号名称及其编号。
  • -s SIGNAL:显式指定信号名称。
  • -pid:目标进程 ID,可以是一个或多个。

举例说明

  • 发送默认信号(SIGTERM)

    kill 1234(某个进程的PID)

    默认发送 SIGTERM 信号,通常用于优雅地终止进程。

  • 发送特定信号
    强制终止进程可以使用 SIGKILL(信号编号 9):

    kill -9 1234
  • 列出所有信号
    查看系统支持的信号列表:

    kill -l

3.使用函数产生信号

3.1 kill 函数

kill 是用于向任意进程发送信号的系统调用,其语法如下:

#include <sys/types.h>
#include <signal.h>int kill(pid_t pid, int sig);
  • 参数说明

    • pid:目标进程的 PID。
      • > 0:向指定的单个进程发送信号。
      • = 0:向调用进程所在的进程组发送信号。
      • < -1:向特定进程组发送信号。
    • sig:要发送的信号类型(如 SIGINTSIGKILL)。
  • 示例: 向当前进程发送 SIGTERM 信号:

    #include <signal.h>
    #include <unistd.h>int main() {kill(getpid(), SIGTERM);return 0;
    }
    

3.2 raise 函数

raise 是一个标准库函数,用于向自身发送信号,其本质是对 kill 函数的封装。语法如下:

#include <signal.h>int raise(int sig);
  • 参数说明

    • sig:要发送的信号。
  • 特点

    • 只能向当前进程发送信号。
    • 使用方便,不需要获取 PID。
  • 示例: 触发 SIGINT 信号:

    #include <signal.h>
    #include <stdio.h>void signal_handler(int sig) {printf("Caught signal: %d\n", sig);
    }int main() {signal(SIGINT, signal_handler); // 注册信号处理函数raise(SIGINT); // 发送信号return 0;
    }
    

3.3 abort 函数

abort 是一个标准库函数,用于向自身发送 SIGABRT 信号,强制使程序异常终止,并生成核心转储文件(core dump)。语法如下:

#include <stdlib.h>void abort(void);
  • 特点

    • 触发 SIGABRT 信号。
    • 通常用于在程序遇到严重错误时调用。
    • 如果未捕获 SIGABRT,程序将直接退出。
  • 示例: 强制终止程序并生成 core dump:

    #include <stdlib.h>int main() {abort();return 0;
    }
    

4.由软件条件产生信号

除了用户手动触发信号和程序显式调用信号函数外,信号也可以在程序运行时,由特定的软件条件自动触发。例如,管道写入异常会触发 SIGPIPE 信号,定时器到期会触发 SIGALRM 信号。

4.1 SIGPIPE 信号

  • 触发条件
    当一个进程尝试向已经关闭的管道(pipe)或套接字(socket)写入数据时,系统会自动发送 SIGPIPE 信号。默认行为是终止进程。

  • 常见场景
    例如,父进程向关闭的管道写入数据:

    #include <unistd.h>
    #include <signal.h>
    #include <stdio.h>int main() {int fds[2];pipe(fds);           // 创建管道close(fds[0]);       // 关闭读端if (write(fds[1], "data", 4) == -1) {  // 写入数据perror("write error");}return 0;
    }
    

    输出类似:

    write error: Broken pipe
  • 解决方式
    捕获 SIGPIPE 信号并进行自定义处理,或者忽略该信号:

    signal(SIGPIPE, SIG_IGN); // 忽略SIGPIPE

4.2 SIGALRM 信号

  • 触发条件
    SIGALRM 信号由 alarm 函数触发,用于在指定的时间间隔后通知进程执行某些任务。

  • alarm 函数
    alarm 函数设置一个秒级定时器,到期时发送 SIGALRM 信号:

    #include <unistd.h>unsigned int alarm(unsigned int seconds);
    
  • 示例
    设置一个 3 秒定时器,触发后执行信号处理函数:

    #include <signal.h>
    #include <unistd.h>
    #include <stdio.h>void handle_alarm(int sig) {printf("Alarm triggered!\n");
    }int main() {signal(SIGALRM, handle_alarm); // 注册处理函数alarm(3);                      // 设置定时器pause();                       // 等待信号return 0;
    }
    

    输出类似:

    Alarm triggered!
  • 取消定时器
    再次调用 alarm 函数,传入 0 即可取消定时器:

    alarm(0);

5.硬件异常产生信号

在程序运行过程中,某些硬件异常(例如非法操作或内存访问)会触发系统向进程发送特定信号。这些信号通常表示程序存在错误,默认行为是终止程序运行,并可能生成 核心转储文件(core dump)

5.1 常见硬件异常信号

5.1.1 除 0 操作:SIGFPE 信号

  • 触发条件
    当程序执行非法的算术运算(如整数除以 0)时,会触发 SIGFPE 信号(Floating Point Exception)。默认行为是终止进程。

  • 示例代码
    以下代码试图执行除以 0 的操作:

    #include <stdio.h>int main() {int a = 1;int b = 0;printf("%d\n", a / b); // 除以 0return 0;
    }
    

    结果:程序崩溃,触发 SIGFPE

  • 捕获信号
    使用信号处理函数捕获 SIGFPE

    #include <signal.h>
    #include <stdio.h>void handle_sigfpe(int sig) {printf("Caught SIGFPE: Illegal operation\n");
    }int main() {signal(SIGFPE, handle_sigfpe);int a = 1, b = 0;printf("%d\n", a / b);return 0;
    }
    

5.1.2 访问野指针:SIGSEGV 信号

  • 触发条件
    当程序尝试访问非法内存地址(如空指针或已释放的内存)时,会触发 SIGSEGV 信号(Segmentation Fault)。默认行为是终止进程。

  • 示例代码
    以下代码访问了一个空指针:

    #include <stdio.h>int main() {int *ptr = NULL;*ptr = 42; // 访问空指针return 0;
    }
    

    结果:程序崩溃,触发 SIGSEGV

  • 捕获信号
    可以捕获 SIGSEGV 信号来处理异常:

    #include <signal.h>
    #include <stdio.h>void handle_sigsegv(int sig) {printf("Caught SIGSEGV: Invalid memory access\n");
    }int main() {signal(SIGSEGV, handle_sigsegv);int *ptr = NULL;*ptr = 42;return 0;
    }
    

5.2 核心转储(Core Dump)

核心转储是一种调试工具,用于记录程序崩溃时的内存状态,帮助开发者排查问题。

生成核心转储

  1. 启用核心转储
    默认情况下,核心转储可能被限制或禁用。可以使用以下命令启用:

    ulimit -c unlimited
  2. 运行出错程序
    当程序崩溃时,系统会生成核心转储文件,通常命名为 corecore.<pid>

  3. 调试核心转储
    使用调试工具 gdb 分析核心转储文件:

    gdb ./program core

    在调试器中,可以查看崩溃时的调用堆栈和内存状态。

示例调试

假设程序崩溃生成了核心转储文件,可以通过以下命令进入调试器:

gdb ./a.out core

进入调试器后,运行 bt(backtrace)命令查看调用堆栈:

bt (进入gdb调试后)

6.小结

本篇博客全面介绍了 Linux 系统中信号的产生方式,从终端按键、系统命令,到函数调用和软件条件触发,再到硬件异常的信号处理。信号作为进程间通信和异常管理的关键机制,贯穿了用户操作、程序设计和系统运行的各个层面。理解信号的来源和触发方式,是深入学习 Linux 信号处理与调试技巧的重要基础,为编写健壮的程序提供了强有力的支持。

http://www.khdw.cn/news/9428.html

相关文章:

  • 网站建设功能定位怎么写windows优化大师收费
  • 前端h5是什么意思南宁网络优化seo费用
  • 想建网站网站加速器
  • 网站上可以做文字链接么佛山今日头条
  • 交互式网站备案难吗百度快速收录提交工具
  • 免费图片素材网站有哪些佛山网站建设制作公司
  • 那里可以做网站外贸seo网站
  • 网站招聘方案怎么做网站分析报告
  • 网站建设要经历哪些步骤网站页面
  • 个人网站建设实训目的宣传链接怎么做
  • 从哪看出网站的建站公司网上做广告宣传
  • 南京装修公司常用的seo工具
  • 养一个空壳公司的好处搜索引擎优化培训中心
  • 网站建设公司销售招聘seo的研究对象
  • 北京企业网站推广价格图床外链生成工具
  • 天津做网站哪家公司好无锡网站建设seo
  • 企业网站新闻wp怎么做上海百度公司地址在哪里
  • 王烨飞微博关键词快速排名seo怎么优化
  • 太原做app网站建设友情链接交易网
  • 重庆网站建设哪个公司好seo推广薪资
  • vue门户网站模板深圳头条新闻
  • 济南家居行业网站开发宣传推广网络推广
  • 济宁网站建设优化广州seo优化公司排名
  • 定制网站建设的流程今天的国内新闻
  • 网站怎么做json数据独立网站怎么做
  • 加入网站帮忙做网站网站改版
  • 南京网站建设 零云建站室内设计培训班学费一般多少
  • 百度怎么建设网站2022今日最新军事新闻
  • 网站建设翻译谁提供谷歌官网下载app
  • 网站开发需要的所有技术西安计算机培训机构排名前十