首页 > 系统相关 >Linux的信号管理 [补档-2023-07-30]

Linux的信号管理 [补档-2023-07-30]

时间:2024-01-13 17:23:13浏览次数:29  
标签:11 函数 sigset int 30 信号 Linux 进程 07

信号

11-1简介:

​ 信号只是表示某个信号,不可以携带大量信息,信号需要满足特点的条件才会产生。是一种特别的通信手 段。

11-2 信号机制:

​ 假设有两个进程A,B,现在进程A给进程B发送信号,进程B在收到信号之前会执行自己的代码,当收到 信号后,无论执行到了哪里,都要暂停执行然后去处理信号。当处理完信号后再接着执行。类似于硬件中的中 断。但信号是在软件层面上实现的中断,常备称为软中断。

​ 每个进程所收到的信号都是由内核负责发送的,也就是说进程A会将信号发给内核,然后内核再将信号转 发给进程B。由此可以得出信号的实现具有一定的延时性。

​ 在pcb进程控制块中,结构体task struct中也包含了信号的相关信息。

11-3 信号的状态:

​ 分为三种状态:产生,未决和递达。

​ 产生:

​ 按键产生:ctrl+c ,ctrl+z ,ctrl+\

​ 系统调用产生:kill,raise,about

​ 软件条件产生:定时器alarm

​ 硬件异常产生:段错误,内存对齐出错,除0.

​ 未决:介于产生和递达之间,未决状态下的信号在等待处理,至于为什么等待可能是被阻塞了。

​ 递达:信号已经被送到目标进程,并且等待处理。

11-4 阻塞信号集和未决信号集

​ 阻塞信号集:里面保存的是当前进程被阻塞的信号,当进程收到了阻塞信号集中的信号,则可以先放一放 这些信号,不予处理,先去干别的。

​ 未决信号集:当信号产生后由于某些原因可能没有被处理,则这些信号会被存储在这里。

​ 关系:当一个信号被产生时,他首先会进入未决信号集,然后根据进程当前的信号阻塞状态来决定是否进 入递达状态。如果阻塞信号集在有相应的信号被阻塞,则该信号会一直保持在未决状态,直到接触阻塞。有相 应的函数可以选择性地阻塞和屏蔽信号。

11-5 信号的四要素:

​ 1.信号的编号:可以通过kill -l命令来查看当前系统有哪些信号。1到31号的信号为常规信号,34到36 为实时信号。

​ 2.信号的名称:例如SIGINT表示中断信号。

​ 3.产生信号的事件:例如用户按下crlt+z会终止程序。

​ 4.信号的默认处理动作:例如crlt+z产生的信号它的处理动作是终止程序的执行。

以下是常见的信号,前面的数字是信号的编号,后面的大写字母是信号名称。

1 SIGHUP(挂起):终端连接断开。

2 SIGINT(中断):用户按下Ctrl+C键。

3 SIGQUIT(退出):用户按下Ctrl+\键。

4 SIGILL(非法指令):进程执行了非法的CPU指令。

6 SIGABRT(中止):进程发生异常终止。

8 SIGFPE(浮点异常):发生浮点运算错误。

9 SIGKILL(强制终止):无条件终止进程。

11 SIGSEGV(段错误):进程访问了未分配给它的内存段。

13 SIGPIPE(管道破裂):写入已关闭的管道或读取没有打开的管道。

14 SIGALRM(闹钟超时):计时器到达指定时间。

15 SIGTERM(终止):请求进程正常终止。

30 SIGUSR1(用户自定义信号1):用户定义的信号1。

31 SIGUSR2(用户自定义信号2):用户定义的信号2。

11-6 信号相关函数:

11-6-1 signal函数:

头文件:#include <signal.h>

函数原型:

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum , sighander_t handler);

​ 解析:使用typedef重新定义了一个函数指针类型sighandler_t,并且指向接受一个int类型参数并返 回void的函数的指针类型。

函数作用:注册信号捕捉函数。

函数参数

signum:信号编号。(填写信号的名称)

handler:信号处理函数。

函数返回值:成功则返回一个指向之前信号处理函数的指针。失败则返回SIG_ERR。

11-6-2 kill函数/命令:

函数/命令的功能:给指定的进程发生指定的信号。

kill命令:

kill [options] <pid>

options

​ -l 列出所有可用的信号名称。

​ -s <信号名称> 指定要发送的信号。

​ -<信号名称> 同上。

​ -p 不发送信号,仅打印与指定进程匹配的进程ID。

​ -a 打印进程的详细信息。

pid:进程的pid。

kill函数:

头文件:#include <signal.h>

函数原型:int kill(pid_t pid , int sig);

函数参数

pid

​ pid大于0:发送信号给指定的进程。

​ pid等于0:发送信号给与调用kill函数属于同一进程组的所有进程。

​ pid小于-1:取pid的绝对值,然后给对应的进程发信号。

​ pid等于-1:向当前会话中的所有进程发送信号。

sig信号参数:填入要使用的信号名称。

函数返回值:成功返回0,失败返回-1.

​ 进程组:一组有关联的进程的集合。

11-7 raise函数和abort函数:

11-7-1 raise函数:

头文件:#include <signal.h>

函数原型:int raise(int sig);

函数功能:给自己发信号。

函数参数:信号的名称。

函数返回值:成功返回0,失败返回非0值。

11-7-2 abort函数:

头文件:#include <signal.h>

函数原型:void abort(void);

函数功能:给自己发送异常终止信号 6 SIGABRT,并且产生core文件。

函数无返回值和函数参数

11-8 alarm函数:

头文件:#include <unistd.h>

函数原型:unsigned int alarm(unsigned int seconds);

函数功能:设置定时器,在指定的seconds后,内核会给当前进程发送 14 SIGALRM信号,当进程收到该 信号,则默认动作终止。每一个进程只能有一个定时器。

函数参数:填等待秒数。

函数返回值:返回0或者剩余的秒数,不存在调用失败的情况。

​ 其他操作:可以给alarm的值设置为0来关闭已经设置好的定时器。

11-9 setitimer函数:

头文件:#include <sys/time.h>

函数原型:int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);

函数功能:设置定时器,可以代替alarm函数,精度为微妙,可以实现周期定时。

函数参数

which:指定定时方式。

自然定时:ITIMER_REAL 使用真实时间最为计时器的基准。

虚拟空间计时(用户空间):ITIMER_VIRTUAL 使用进程在用户态运行的虚拟时间作为计时器的基准。

运行时计时(用户+内核):ITIMER_PROF使用进程在用户态和内核态运行的虚拟时间作为计时器的基准.

new_value:struct itimerval,负责设定timeout时间。

itimerval.it_value:设定第一次执行function所延迟的秒数。(时钟触发时间)

itimerval.it_interval:设定以后每几秒执行function。(时钟触发周期)

​ old_value:存放旧的timeout值,一般指定为NULL

函数返回值:成功返回0,失败返回-1.

11-10 信号集相关函数 (需包含头文件头文件:#include <signal.h>)

11-10-1 sigemptyset函数:

函数原型:int sigemptyset(sigset_t *set);

函数功能:将某个信号集清0.

函数参数set参数是一个指向sigset_t类型的指针,表示要操作的信号集。

函数返回值:成功返回0,失败返回-1.

11-10-2 sigfillset函数:

函数原型:int sigfillset(sigset_t *ser);

函数功能:将某个信号集置1.

函数参数set参数是一个指向sigset_t类型的指针,表示要操作的信号集。

函数返回值:成功返回0,失败返回-1.

11-10-3 sigaddset函数:

函数原型:int sigaddset(sigset_t *set, int signum);

函数功能:将某个信号加入到信号集中。

函数参数

set:它是一个指向sigset_t类型的指针,表示要操作的信号集。

signum:它是信号的名称。

函数返回值:成功返回0,失败返回-1.

11-10-4 sigdelset函数:

函数原型:int sigdelset(sigset_t *set, int signum);

函数功能:将某个信号从信号集中清除掉。

函数参数

set:它是一个指向sigset_t类型的指针,表示要操作的信号集。

signum:它是信号的名称。

函数返回值:成功返回0,失败返回-1.

11-10-5 sigismember函数:

函数原型:int sigismember (const sigset_t *set, int signum);

函数功能:判断某个信号是否在信号集中。

函数参数

set:它是一个指向sigset_t类型的指针,表示要操作的信号集。

signum:它是信号的名称。

函数返回值

​ 如果存在则返回1。

​ 如果不存在则返回0。

​ 如果调用出错则返回-1。

11-10-6 sigprocmask函数:

函数原型:int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

函数功能:用来检查和修改进程的信号屏蔽字。

函数参数

how:指定了对信号屏蔽字的操作方式。

SIG_BLOCK:将set指向的信号集中的信号添加到当前信号屏蔽字中。如果信号已经被阻塞则任然保持阻塞状态。

SIG_UNBLOCK:从当前信号屏蔽字中解除set指向的信号集中的信号的阻塞。

SIG_SETMASK:使用set指向的信号集替换当前的信号屏蔽字。

set:是一个指向sigset_t类型的指针,表示要设置的新的信号屏蔽字。sigset_t是一个位向量表示多个 信号。

oldset:是一个指向sigset_t的指针,用于存储旧的信号屏蔽字,如果不需要保存旧的则可以填NULL。

函数返回值:成功返回0,失败fanhui-1。

11-10-7 sigpending函数:

头文件:#include <signal.h>

函数原型:int sigpending(sigset_t *set);

函数功能:读取当前进程的未决信号集。

函数参数set参数是一个指向sigser_t类型的指针,用于存储当前进程的未决信号集。。

函数返回值:成功返回0,失败返回-1。

11-11 信号捕捉函数sigaction

头文件:#include <signal.h>

函数原型:int sigaction(int signum, const struct sigaction *acr, struct sigaction *oldact);

函数功能:注册一个信号处理函数。

函数参数

signum:要捕捉的信号。

act:新的处理方式

oldact:旧的处理方式。

函数参数中的结构体定义:

​ struct sigaction {

​ void (*sa_handler)(int); // 信号处理函数

​ void (*sa_sigaction)(int, siginfo_t *, void *); //信号处理函数

​ sigset_t sa_mask; //信号处理函数执行期间需要阻塞的信号

​ int sa_flags; //通常为0,表示使用默认标识

​ void (*sa_restorer)(void);

​ };

结构体成员变量的具体意义:

​ sa_handler:指定信号捕捉后的处理函数名。当信号出现时,则使用这个函数进行处理。

​ sa_mask:用来指定在信号处理函数执行的期间,要被屏蔽的信号。

​ sa_flags:额外选项。可以默认设置为0。

SA_RESTART:使被信号中断的系统调用自动重启。

SA_NOCLDSTOP:终止子进程时,不产生 SIGCHLD 信号。

SA_SIGINFO:指定 sa_sigaction 字段作为信号处理函数,并允许传递附加信息。

​ sa_restorer:一般设置为NULL,在最新的linux内核中,他已经被忽略。

函数返回值:成功返回0,失败返回-1。

标签:11,函数,sigset,int,30,信号,Linux,进程,07
From: https://www.cnblogs.com/xiaobai1523/p/17962615

相关文章

  • Linux文件IO之二 [补档-2023-07-21]
    8-5linux系统IO函数:open函数:​函数原型:intopen(constchar*pathname,intflags,mode_tmode);​功能:打开一个文件并返回文件描述符。与c库中的fopen差不多​参数:pathname:要打开的文件路径名。flags:打开文件的标志O_RDONLY(只读)O_WRONLY(只写)O_RD......
  • Linux的进程管理 [补档-2023-07-25]
    Linux进程管理9-1并发与并行:​并发:在同一个cpu上,并且在一个时间段时,同时运行多个程序。比如在1000毫秒内,我们有5个程序需要执行,所以我们可以将1000毫秒分为5个200毫秒,让每个程序都占用200毫秒的cpu使用权,这样在1000毫秒内就可以执行5个程序。​并行:大于等......
  • GDB调试程序 [补档-2023-07-19]
    gdb调试​它是gcc的调试工具,调试工具都能干什么就不多说了。7-1生成调试信息​在使用gcc编译c/c++的程序时,需要在编译命令中加入-g这一参数,它可以为你显示函数名,变量名等待。例如:gcc-gtest.c-otest​7-2启动gdb调试信息​启动指令:gdb可执行程序......
  • Linux文件IO之一 [补偿-2023-07-21]
    Linux文件IO8-1C标准库IO函数的工作流程​使用fopen函数打开一个文件,之后会返回一个FILE*fp指针,fp指针指向一个结构体,这个结构体是c标准io库中的一个结构体,这个结构体有三个重要的成员:文件描述符:描述符指向一个打开文件表,通过此表可以找到文件的inode表,通过对应的in......
  • MakeFile文件的使用 [补档-2023-07-13]
    makefile-gdb文件​可以在文件中指定那些文件可以先进行编译,那些文件可以后进行编译,那些文件可以重新编译。他可以自动化编译程序。。。。6-1makefile基本规则​如下:​目标:依赖​(tab)命令​规则三要素:目标:要生成的目标文件。依赖:目......
  • Linux下的gcc/g++编译器的使用 [补档-2023-06-13]
    gcc编译器​这东西是Linux上的c/c++编译器。5-1gcc的工作流程5-2gcc的常用参数-v查看gcc版本号,--version也可以-E生成预处理文件-S生成汇编文件-c只编译,生成.o文件,通常称为目标文件-I指定头文件所在的路径-L指定库文件所在的路径-l指定库的名......
  • Linux系统的一些实用操作 [补档-2023-07-30]
    Linux的实用操作4-1.常用快捷键强制停止:当某些程序运行时,或者命令输入错误时,可以通过ctrl+c来强制结束当前的操作。退出或登出:当我们要退出某些用户时,或者要退出某些特殊的页面可以使用ctrl+d来进行。(vi/vim不可用)历史命令搜索:通过输入history命令来查看之前输入......
  • Linux的用户和权限 [补档-2023-07-07]
    Linux用户和权限3-1.su用户切换命令exit用户退出命令​用户切换命令的语法:​su[-][用户名]​其中:​-可选,表示是否在切换用户后加载环境变量,建议带上。​用户名可选,表示要切换到那个用户,如果不填则默认切换到root用户上。​......
  • Linux 系统开机启动项清理
    通常情况下,你能用 /etc/init.d 查看系统引导时启动的服务项。但是systemd会用不一样的展现方式,下面是一些命令,用于展示开机启动时的进程项。你可以看到,这里头有一项是蓝牙,我不需要使用它,那么我应该怎样关闭并阻止它在开机时后启动?完成上面的操作之后,用下面的命令来确定自己是否......
  • vi / vim编辑器的使用 [补档-2023-07-01]
    vi/vim编辑器​vi/vim编辑器是linux中的文本编辑器,其中vim比vi的功能更加强大,可以编辑shell程序,推荐使用vim,下面也将介绍vim如何使用。2-1vi/vim的三种工作模式命令模式​在此模式下,所敲的每一个键都是一个命令,不可以进行文本编辑。比如输入w代表保存等待。输入......