[Linux]信号入门

发布于:2025-06-29 ⋅ 阅读:(20) ⋅ 点赞:(0)

一、生活中的信号

生活中会产生很多信号

  • 等待红绿灯的信号
  • 网购后等待取件的信号
  • 平台上订购外卖后到达通知的信号

往往我们人接收信号后会有三类不同的动作,比如:

  • 默认执行(红灯停绿灯行、马上取快递、马上拿外卖)
  • 进行自定义动作(边唱歌边等红绿灯、边打电话边取件)
  • 选择忽略(忽略红绿灯直接闯、忽略外卖继续打游戏

然而,在信号产生之前,我们是不清楚信号会什么时候产生?,则称为:我们和信号之间是异步的。


二、进程中的信号

1.基础理解

我们先执行一段程序:

#include<iostream>
#include<unistd.h>

using namespace std;

int main()
{
    while (true)
    {
        cout << "hello, i am a process !!!" << endl;
        sleep(1);
    }
    return 0;
}

执行结果:
在这里插入图片描述
从结果我们可以看到,我们输入 “CTRL+C” 后,程序被终止了。原因就是按下 “CTRL+C” 会对程序发出 2号信号 —> 2) SIGINT

2.Linux中的31个普通信号

使用 kill -l 进行查阅

在这里插入图片描述
我们一般只研究前31个。前31个被称为普通信号,其他被称为实时信号

详细内容可查看如下文章:
Linux中31个普通信号含义解读


三、几个传输信号的函数接口

1.系统调用kill函数&&模拟实现

KILL(2)
NAME
       kill - send signal to a process

SYNOPSIS
       #include <sys/types.h>
       #include <signal.h>

       int kill(pid_t pid, int sig);
       //pid:目标进程的pid。sig:几号信号
		成功时(至少发送了一个信号),返回零。出现错误时,返回 -1,并设置errno

kill函数可以向任意进程发送任意信号,
kill命令底层实际上就是kill系统调用,信号的发送由用户发起,而执行者是OS。

发送信号的能力是OS的,但是有这个能力并不一定有使用这个能力的权力,一般情况下用户决定OS向目标进程发信号。所以OS有这个能力,那么对外提供能力只能通过系统调用的接口的方式来让用户向目标进程发送信号。

kill函数模拟实现如下

#include<iostream>
#include<unistd.h>
#include<sys/types.h>
#include<signal.h>
#include<string>
using namespace std;

void Usage(string proc)
{
    cout << "Usage:\n\t" << proc << " signum pid\n\n";
}
int main(int argc, char *argv[])
{
    //usage: ./mykill signum pid
    if (argc != 3)
    {
        Usage(argv[0]);
        exit(1);
    }

    int signum = stoi(argv[1]);
    pid_t pid = stoi(argv[2]);

    int ret = kill(pid, signum);
    if (ret == -1)
    {
        perror("kill");
        exit(2);
    }

    return 0;
}
//myproc.cc
#include<iostream>
#include<unistd.h>
using namespace std;

int main()
{
    while (true)
    {
        cout << "hello, i am a process, pid is " << getpid() << endl;
        sleep(1);
    }
    return 0;
}

实现效果
在这里插入图片描述

2.raise函数

raise函数可以让进程给自己发送任意信号。

RAISE(3)
NAME
       raise - send a signal to the caller

SYNOPSIS
       #include <signal.h>

       int raise(int sig);
      
RETURN VALUE
     raise() returns 0 on success, and nonzero for failure.
#include<iostream>
#include<unistd.h>
#include<sys/types.h>
#include<signal.h>
using namespace std;

int main()
{
    int cnt = 10;
    while (cnt--)
    {
        cout << "i am a process!!!" << endl;
        sleep(1);
        if (cnt == 5)
        {
            raise(3);//kill(getpid(), 3);
        }
    }
    return 0;
}

实现效果
在这里插入图片描述

3.abort函数

abort终止进程的方式,给自己发送指定的信号 6) SIGABRT 。

ABORT(3)
NAME
       abort - cause abnormal process termination

SYNOPSIS
       #include <stdlib.h>

       void abort(void);

RETURN VALUE
       The abort() function never returns.
#include<iostream>
#include<unistd.h>
#include<sys/types.h>
#include<signal.h>
#include<cstdlib>
#include<string>
using namespace std;

int main()
{
    int cnt = 10;
    while (cnt--)
    {
        cout << "i am a process!!!" << endl;
        sleep(1);
        if (cnt == 5)
        {
            abort();
            //kill(getpid(), 6);
        }
    }
    return 0;
}

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到