前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Linux】详解信号产生的方式

【Linux】详解信号产生的方式

作者头像
用户10923276
发布2024-05-03 08:36:57
970
发布2024-05-03 08:36:57
举报

一、kill命令

在命令行中通过kill -数字 pid指令可以给指定进程发送指定信号。这里说明一下几个常见的信号:

  • SIGINT(2号信号):中断信号,通常由用户按下Ctrl+C产生,用于通知进程终止。
  • SIGQUIT(3号信号): 终止进程并产生core文件,用于后续分析程序崩溃时的状态和数据。
  • SIGKILL(9号信号):强制终止信号,不能被进程捕获或阻塞,用于强制结束进程。
  • SIGSTOP(20号信号):停止信号,使进程停止执行,直到收到SIGCONT信号。
  • SIGCONT(18号信号):继续信号,使之前被SIGSTOP信号停止的进程继续执行。
  • SIGALRM(14号信号):闹钟信号,当由alarm函数设置的定时器时间已经超过时产生。

如果想查阅更多的信号,可以使用man 7 signal指令在官方手册中进行查找。

二、键盘产生信号

不同的操作系统产生信号的键盘组合键可能不同,这里说的是ubuntu系统下。常见的键盘产生的信号有:

ctrl + c:向当前进程发送2号信号。 ctrl + \:向当前进程发送3号信号。 ctrl + z:向当前进程发送20号信号。

三、系统调用产生信号

3.1、kill系统调用函数

二号手册查询。pid就是进程pid,指要向哪一个进程发信号,sig指要发送几号命令。

3.2、raise系统调用函数

三号手册查询。raise就是一个用来给进程自己发信号的系统调用函数。sig指要发送哪一个信号。

3.3、abort系统调用函数

三号手册。abort系统调用函数就是一个用来给进程自己发送6号信号的系统调用函数。

四、软件条件产生信号

在操作系统中,由软件条件产生的信号通常指的是通过某种软件操作或系统状态触发的信号。这些信号用于通知进程某个特定事件已经发生。下面会说明常见的软件条件:

4.1、管道通信

【Linux】匿名管道实现简单进程池-CSDN博客之前在这一篇博客中,我已经介绍了进程间使用管道通信的四种情况和五种特性,其中在第四种情况中,我曾经说过,读端关闭了,操作系统就会发送信号直接杀死进行写入的进程,因为没有读端写入也就没有了意义。此时操作系统给写端进程发送的正是SIGPIPE(十三号信号)直接终止写端进程。

4.2、时钟信号

调用alarm函数可以设定一个闹钟,也就是告诉内核在seconds秒之后给当前进程发SIGALRM信号, 该信号的默认处理动作是终止当前进程。

代码语言:javascript
复制
#include <unistd.h>
unsigned int alarm(unsigned int second);

second参数设置的是经过多少秒后向该进程发送时钟信号函数的返回值是0或者是以前设定的闹钟时间还余下的秒数

代码语言:javascript
复制
#include <iostream>
#include <unistd.h>
#include <signal.h>
using namespace std;

void handler(int signo)
{
    cout << "hello signal" << endl;
}

int main()
{
    signal(SIGALRM, handler);
    //5秒后闹钟响起,执行自定义方法
    alarm(5);
    while (true)
    {
        cout << "I am a process! my pid is " << getpid() << endl;
        sleep(1);
    }
    
    return 0;
}

经过5秒,我们果然看到了进程收到了闹钟信号,执行了自定义方法。

但如果我们前一个闹钟还没响我们又设了一个闹钟,新设置的闹钟先响了这时alarm函数的返回值就是以前设定的闹钟时间还余下的秒数。假设我此时先设置了一个500秒以后才响的闹钟,在自定义函数中又设置了5秒以后响的闹钟,然后在命令行中给这个进程提前发送闹钟信号。看代码和结果:

代码语言:javascript
复制
#include <iostream>
#include <unistd.h>
#include <signal.h>
using namespace std;

void handler(int signo)
{
    cout << "hello signal" << endl;
    //又设置了一个5秒后响的闹钟
    unsigned int n = alarm(5);
    cout << "还剩" << n << "秒" << endl;
}

int main()
{
    signal(SIGALRM, handler);
    alarm(500);
    while (true)
    {
        cout << "I am a process! my pid is " << getpid() << endl;
        sleep(1);
    }
    
    return 0;
}

此时在命令行中提前发送闹钟信号:

我们可以看到第二个设置的闹钟的返回值为490,也就是上一个闹钟还没有跑完的时间。之后就是每隔5秒闹钟响一次。

五、异常产生信号

常见的进程出异常产生信号有除0异常,操作系统会向进程发送8号信号(SIGFPE)。野指针,操作系统会向进程发送11号信号(SIGSEGV)。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-05-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、kill命令
  • 二、键盘产生信号
  • 三、系统调用产生信号
    • 3.1、kill系统调用函数
      • 3.2、raise系统调用函数
        • 3.3、abort系统调用函数
        • 四、软件条件产生信号
          • 4.1、管道通信
            • 4.2、时钟信号
            • 五、异常产生信号
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档