linux系列signal函数详解(代码片段)

飞翔的鲲 飞翔的鲲     2023-03-28     613

关键词:

Date: 2023.1.18


文章目录

转载自:http://imhuchao.com/2300.html

signal作用是为信号注册一个处理器。这里的“信号”是软中断信号,这种信号来源主要有三种:

程序错误:比如除0,非法内存访问。
外部信号:终端Ctrl-C产生的SIGINT信号,定时器产生的SIGALERM。
显示请求:kill函数发送的任意信号。
当kill一个进程的时候,默认会发送SIGTERM信号,此时这个信号只有默认处理操作(SIG_DFL),直接中断进程执行。如果此时该进程正在执行一个任务,直接终止该进程会导致任务没有完成。这个时候为SIGTERM信号注册一个信号处理函数就十分有必要。

1、介绍

typedef void (*sighandler_t) (int);
sighandler_t signal (int sig, sighandler_t handler)

参数:

sig要设置信号处理函数的信号。它可以是实现定义值或下例值之一:
SIGABRT
SIGFPE
SIGILL
SIGINT
SIGSEGV
SIGTERM
定义信号类型 (宏常量)

handler 信号处理函数。这必须是下列之一:SIG_DFL 宏。信号处理函数被设为默认信号处理函数。SIG_IGN 宏。忽略信号。指向函数指针。函数签名必须等价于如下:extern “C” void fun(int sig);

返回值:成功时为先前的信号处理函数,失败时为 SIG_ERR (某些实现上能禁用设置信号处理函数)。

使用:使用方法请直接看下面的例子。注册一个信号用于在按下Ctrl-C时不立刻终止进程,而是输出一段文字并sleep一段时间。

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

bool is_stop = false;
void quit_handler(int signo) 
    is_stop = true;
    std::cout << "stopping\\n";
    sleep(2);


int main() 
    auto prev = signal(SIGINT, quit_handler);
    if (prev == SIG_ERR) 
        abort();
    
    while (!is_stop) 
        std::cout << "running\\n";
        sleep(1);
    
    std::cout << "stopped\\n";

2、如何安装多个处理函数

signal只能为一个信号添加一个处理函数,添加多个处理函数时后面的函数会覆盖前面的函数。看如下代码

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

bool is_stop = false;
void quit_handler1(int signo) 
    is_stop = true;
    std::cout << "handler1\\n";
    sleep(2);


void quit_handler2(int signo) 
    is_stop = true;
    std::cout << "handler2\\n";
    sleep(2);


int main() 
    auto prev1 = signal(SIGINT, quit_handler1);
    auto prev2 = signal(SIGINT, quit_handler2);

    if (prev1 == SIG_ERR || prev2 == SIG_ERR) 
        abort();
    
    while (!is_stop) 
        std::cout << "running\\n";
        sleep(1);
    
    std::cout << "stopped\\n";

运行之后按下Ctrl-C,结果发现只有handler2有效,handler1失效了。

3、信号列表

SignalDescription
SIGABRT由调用abort函数产生,进程非正常退出
SIGALRM用alarm函数设置的timer超时或setitimer函数设置的interval timer超时
SIGBUS某种特定的硬件异常,通常由内存访问引起
SIGCANCEL由Solaris Thread Library内部使用,通常不会使用
SIGCHLD进程Terminate或Stop的时候,SIGCHLD会发送给它的父进程。缺省情况下该Signal会被忽略
SIGCONT当被stop的进程恢复运行的时候,自动发送
SIGEMT和实现相关的硬件异常
SIGFPE数学相关的异常,如被0除,浮点溢出,等等
SIGFREEZESolaris专用,Hiberate或者Suspended时候发送
SIGHUP发送给具有Terminal的Controlling Process,当terminal 被disconnect时候发送
SIGILL非法指令异常
SIGINFOBSD signal。由Status Key产生,通常是CTRL+T。发送给所有Foreground Group的进程
SIGINT由Interrupt Key产生,通常是CTRL+C或者DELETE。发送给所有ForeGround Group的进程
SIGIO异步IO事件
SIGIOT实现相关的硬件异常,一般对应SIGABRT
SIGKILL无法处理和忽略。中止某个进程
SIGLWP由Solaris Thread Libray内部使用
SIGPIPE在reader中止之后写Pipe的时候发送
SIGPOLL当某个事件发送给Pollable Device的时候发送
SIGPROFSetitimer指定的Profiling Interval Timer所产生
SIGPWR和系统相关。和UPS相关。
SIGQUIT输入Quit Key的时候(CTRL+\\)发送给所有Foreground Group的进程
SIGSEGV非法内存访问
SIGSTKFLTLinux专用,数学协处理器的栈异常
SIGSTOP中止进程。无法处理和忽略。
SIGSYS非法系统调用
SIGTERM请求中止进程,kill命令缺省发送
SIGTHAWSolaris专用,从Suspend恢复时候发送
SIGTRAP实现相关的硬件异常。一般是调试异常
SIGTSTPSuspend Key,一般是Ctrl+Z。发送给所有Foreground Group的进程
SIGTTIN当Background Group的进程尝试读取Terminal的时候发送
SIGTTOU当Background Group的进程尝试写Terminal的时候发送
SIGURG当out-of-band data接收的时候可能发送
SIGUSR1用户自定义signal 1
SIGUSR2用户自定义signal 2
SIGVTALRMsetitimer函数设置的Virtual Interval Timer超时的时候
SIGWAITINGSolaris Thread Library内部实现专用
SIGWINCH当Terminal的窗口大小改变的时候,发送给Foreground Group的所有进程
SIGXCPU当CPU时间限制超时的时候
SIGXFSZ进程超过文件大小限制
SIGXRESSolaris专用,进程超过资源限制的时候发

THE END!

linux信号详解:signal与sigaction函数

...也知道了如何修改或者屏蔽默认的信号处理函数。这是本系列文章的最后一篇。在此,我们将通过具体代码实例来深化上述重要概念和方法的理解。【本系列文章目录】操作系统中的信 查看详情

linux信号详解:signal与sigaction函数

...也知道了如何修改或者屏蔽默认的信号处理函数。这是本系列文章的最后一篇。在此,我们将通过具体代码实例来深化上述重要概念和方法的理解。【本系列文章目录】操作系统中的信 查看详情

linux信号详解:signal与sigaction函数

...也知道了如何修改或者屏蔽默认的信号处理函数。这是本系列文章的最后一篇。在此,我们将通过具体代码实例来深化上述重要概念和方法的理解。【本系列文章目录】操作系统中的信 查看详情

linux信号详解:signal与sigaction函数

在此前的系列文章中,我们已经介绍了signal函数的基本用法,本文将通过若干例子帮助读者增进对于它的了解。一、僵尸进程(ZombieProcess)与信号屏蔽(忽略)僵尸进程是当子进程比父进程先结束,而父进程又没有回收子进程... 查看详情

linux信号详解:signal与sigaction函数1

在此前的系列文章中,我们已经介绍了signal函数的基本用法,本文将通过若干例子帮助读者增进对于它的了解。一、僵尸进程(ZombieProcess)与信号屏蔽(忽略)僵尸进程是当子进程比父进程先结束,而父进程又没有回收子进程... 查看详情

lscpu详解(每周一个linux命令系列)(代码片段)

(3)lscpu详解(每周一个linux命令系列)linux命令lscpu详解引言:今天的命令是用来看cpu信息的lscpulscpu我们先看manlscpudisplayinformationabouttheCPUarchitecture翻译:显示cpu架构信息具体的描述如下:lscpugathersCPUarchitectureinformationfromsysfs,/proc/cpuinf 查看详情

ps详解(每周一个linux命令系列)(代码片段)

(5)ps详解(每周一个linux命令系列)linux命令ps详解引言:今天的命令是用来看进程状态的ps命令ps我们先看manpsps-reportasnapshotofthecurrentprocesses.翻译:显示当前进程的快照。ps是ProcessStatus的缩写具体的描述如下:DESCRIPTIONpsdisplaysinformatio... 查看详情

linux——信号详解和实操代码

目录信号的概念信号捕捉初始signal函数    发送信号                通过按键产生信号。kill命令  kill函数raise函数abort函数 alarm函数信号保存的原理信号发送的本质sigset_t类型sigprocmask函数sethowosetsigpending函数      ... 查看详情

万字详解linux系列多线程(下)(代码片段)

...多线程部分内容过多,所以本文接着【万字详解Linux系列】多线程(上)向后介绍多线程相关的内容。一、线程同步1.概念在保证数据安全的前提下,让线程按照某种特定的顺序访问临界资源,从而高效使用临... 查看详情

万字详解linux系列进程控制(代码片段)

文章目录一、环境变量1.基本概念2.常见的环境变量(1)PATH(2)HOME(3)SHELL(4)HISTSIZE(5)SSH_TTY3.与环境变量相关的指令4.在代码中获取环境变量(1)argc和argv(2&#x 查看详情

linux进程通信|信号(代码片段)

...、信号的使用1、注册信号处理函数在C语言中,可以使用signal函数来注册信号处理函数。signal函数原型如下:void(*signal(intsignum,void(*handler)(int)))(int);其中,signum参数表示要注册的信号编号,handler参数表示信号处理函数。signal函数... 查看详情

linux八linux进程信号详解(代码片段)

...迁移到进程1.3 信号概念1.4查看系统定义信号列表1.5 man7signal1.6解释1.2的代码样例1.7信号处理常见方式概览二、产生信号2.1signal函数2.2 通过终端按键产生信号2.3 调用系统函数向进程发信号2.3.1kill函数2.3.2 raise函数2.3.3 abort函数... 查看详情

万字详解linux系列基础io(代码片段)

文章目录前言(1)当前目录(2)stdin、stdout、stderr一、open(1)标志位(2)O_WRONLY(3)O_CREAT二、close,read,write三、文件描述符1.概念2.原理3.分配规则四、重定向1.输出 查看详情

万字详解linux系列基础io(代码片段)

文章目录前言(1)当前目录(2)stdin、stdout、stderr一、open(1)标志位(2)O_WRONLY(3)O_CREAT二、close,read,write三、文件描述符1.概念2.原理3.分配规则四、重定向1.输出 查看详情

万字详解linux系列进程间通信(ipc)(代码片段)

文章目录一、进程间通信1.目的2.如何通信3.分类二、管道1.概念2.匿名管道(1)实现父子进程间通信(2)fork角度的理解(3)文件描述符角度的理解(4)匿名管道特点(5)四种情况(6&#x... 查看详情

linux操作命令分类详解-压缩备份(代码片段)

目录系列文章1、备份还原1.1 tar 备份还原文件2、压缩解压命令2.1打包跟压缩的区别2.2tar打包压缩命令2.3gzip/gunzip 压缩解压命令2.4zip/unzip 压缩解压命令2.5压缩解压命令总结系列文章Linux操作命令分类详解-命令速查(一)... 查看详情

spark函数详解系列之rdd基本转换(代码片段)

摘要: RDD:弹性分布式数据集,是一种特殊集合 ?支持多种来源 ?有容错机制 ?可以被缓存 ?支持并行操作。 RDD有两种操作算子:     Transformation(转换):Transformation属于延迟计算,当一... 查看详情

python编程系列---args与kwargs详解(代码片段)

args与kwargs详解1"""2Process([group[,target[,name[,args[,kwargs]]]]])3-target:目标,指向,表示子进程要执行的代码在target指向的函数中4-args:可变参数,封装在元组中,传递给target指向的函数5-kwargs:关键字参数,封装在字典中,传递给targe... 查看详情