linux 应用开发笔记---【信号:基础】

发布时间:2023年12月17日

1.基本概念

信号是发生事件时对进程的通知机制,也可以称为软件中断

信号的目的是用来通信的

1.硬件发生异常,将错误信息通知给内核,然后内核将相关的信号给相关的进程

2.在终端输入特殊字符产生特殊信号

3.进程调用kill()将任意信号发送给另一个进程或者进程组

?4.发生了软件事件,借助软件触发条件,去进行通知

信号的分类:

1.忽略信号:进程直接不理会信号,除了SIGKILL 和 SIGSTOP

2.捕获信号:当信号达到进程后,执行预先绑定的信号处理函数【插一嘴,这不是就是pyqt5的信号与槽函数】,linux提供了signal()系统调用用于注册信号的处理函数

3. 执行系统的默认操作,进程不进行处理转而让系统进行处理

信号是异步的:

当产生了中断事件,然后告知程序,然后打断当前程序的正常执行流程,跳转去执行中断服务函数

信号的本质是int类型数字编号,从1开始

2.信号的分类

1.可靠信号和不可靠信号

不可靠信号(1-31)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?可靠信号(32-64)

2.实时信号和非实时信号

非实时信号不支持排队,都是不可靠信号-----【标准信号】

实时信号支持排队,是可靠信号

3.进程对信号的处理

1.signal()函数

sig_t signal(int signum, sig_t handler);


signum:此参数指定需要进行设置的信号

handler:sig_t 类型的函数指针,指向信号对应的信号处理函数,当进程接收到信号后会自动执行该处
理函数

2.sigaction()函数

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

signum:需要设置的信号,除了 SIGKILL 信号和 SIGSTOP 信号之外的任何信号


act:描述了信号的处理方式,如果参数 act 为 NULL,则表示无需改变信号当前的处理方式


oldact:如果参数oldact 不为 NULL,则会将信号之前的处理方式等信息通过参数 oldact 返回出来

4.向进程发送信号

一个进程可通过kill()向另一个进程发送信号

int kill(pid_t pid, int sig);

pid:参数 pid 为正数的情况下,用于指定接收此信号的进程 pid


sig:参数 sig 指定需要发送的信号,也可设置为 0,如果参数 sig 设置为 0 则表示不发送信号,但任执
行错误检查,这通常可用于检查参数 pid 指定的进程是否存在。

kill()系统调用可将信号发送给指定的进程或者进程组中的每一个进程

发送进程的权限:


超级用户root:?进程可以将信号发送给任何进程

普通用户:?发送者进程的实际用户 ID 或有效用户 ID 必须等于接收者进程的实际用户 ID 或有效用户 ID

?raise()

int raise(int sig);


sig : 需要发送的信号

alarm()和pause()函数

unsigned int alarm(unsigned int seconds);


设置定时器,当定时器时间到达的时候,内核会向进程发送SIGALR信号,只能触发一次




int pause(void);



pause()系统调用可以使得进程暂停运行、进入休眠状态,直到进程捕获到一个信号为止,只有执行了信
号处理函数并从其返回时,pause()才返回,在这种情况下,pause()返回-1,并且将 errno 设置为 EINTR



5.信号集

定义:一个可以表达多个信号(一组信号)的数据类型

初始化信号集:

int sigemptyset(sigset_t *set);

sigemptyset()初始化信号集,使其不包含任何信号




int sigfillset(sigset_t *set);

sigfillset()函数初始化信号集,使其包含所有信号(包括所有实时信号)

信号集添加/删除信号:
?

sigset_t *set: 信号集


signum:信号


int sigaddset(sigset_t *set, int signum);





int sigdelset(sigset_t *set, int signum);

测试信号是否在信号集

int sigismember(const sigset_t *set, int signum);



在:返回 1
不在:返回0

获取信号的描述信息

char *strsignal(int sig);
psignal() 函数? :作用和perror一样
void psignal(int sig, const char *s);

信号掩码(阻塞信号传递)

处在信号掩码的信号会被阻塞,无法传递给进程进行处理,内核会将其阻塞,直到该信号从信号掩码中移除,内核才会把信号传递给进程从而进行处理

阻塞等待信号sigsuspend()

作用:将恢复信号掩码和pause()挂起进程两个动作封装成一个原子操作

int sigsuspend(const sigset_t *mask);

实时信号:

如果进程当前正在执行信号处理函数,在处理信号期间接收到了新的信号,如果该信号是信号掩码中的 成员,那么内核会将其阻塞,将该信号添加到进程的等待信号集(等待被处理,处于等待状态的信号)中, 为了确定进程中处于等待状态的是哪些信号,可以使用 sigpending()函数获取
int sigpending(sigset_t *set);


set:处于等待状态的信号会存放在参数 set 所指向的信号集中

发送实时信号:

发送进程使用 sigqueue() 系统调用向另一个进程发送实时信号以及伴随数据。
接收实时信号的进程要为该信号建立一个信号处理函数,使用 sigaction 函数为信号建立处理函数,
并加入 SA_SIGINFO ,这样信号处理函数才能够接收到实时信号以及伴随数据,也就是要使用
sa_sigaction 指针指向的处理函数,而不是 sa_handler ,当然允许应用程序使用 sa_handler ,但这样就不能获取到实时信号的伴随数据了

异常退出abort()函数

void abort(void);

正常终止进程:
1.main函数通过return 语句退出程序

2.调用库函数exit()

3.系统调用终止进程,譬如exit(),_Exit()

异常终止进程:
1.被信号终止

2.调用abort函数,SIGABRT

文章来源:https://blog.csdn.net/weixin_63032791/article/details/134862992
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。