目录
alarm函数
raise函数
abort函数
pause函数
转折点
signal函数
可重入函数
信号集
sigemptyset()
sigfillset
sigismember()
sigaddset()
sigdelset()
代码讲解
信号阻塞集
sigprocmask()
alarm函数
相当于一个闹钟,默认动作是终止调用alarm函数的进程,其实也可以处理其他函数,在A进程中使用alarm函数,让B进程退出,至于场景你可以使用单片机的FreeRTOS场景去理解
raise函数
场景分析:比如A进程的功能实现完了,想退出进程了,那么就可以发信号给自己
相当于freertos中的删除任务,本任务的作用就是初始化,任务完成后,我就删除自己释放空间。至于raise会做什么处理我就不知道了,你只需要知道它有这个功能即可
getpid()获取自己的进程号
abort函数
注意:即使SIGABRT信号被加入到了阻塞集的话,一旦使用该函数,还是会被终止。你像上面的alarm函数,产生一个SIGALRM信号,假如SIGALRM这个信号加入到了阻塞集的话,那就无法立马响应了,这就是两者的区别
最后的提醒会有所不一样,alarm是闹钟
pause函数
等待信号的产生,一般是等待另外一个进程或者线程发送信号给我 ,就有点类似于freertos的信号量一样,我设置二值信号量阻塞等待,就有点类似于了。
因此举例的话,你可以创建子进程,父进程使用pause函数,等待子进程发信息给父进程
转折点
我们之前一直讲信号的默认处理方式,那么说明肯定不仅仅是默认处理方式,其处理方式我们可以设定,就像之前的alarm函数肯定不仅仅对调用着,也可以对其他的进程者,任何实现呢?
使用函数signal()
目的:使用alarm函数对其他进程进行暂停处理
signal函数
定义一个函数地址,void*fun();
回调函数使用,跟stm32的HAL库一样,通过信号区分哪一个信号来了
目的:子进程隔1s打印一次son,而父进程隔一秒打印father,并且都是死循环,
当父进程的循环变量为6时,使用alarm(3),并且使用signal函数让它处理子进程,
因此此时子进程会退出,而父进程继续执行
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
int main()
{
__pid_t pid;
pid = fork();
if(pid < 0)
{
perror("fork fail\n");
exit(1);
}
else if(pid == 0)
{
printf("son process\n");
int son ;
for(son=1;son>0;son++)
{
sleep(1);
printf("son\n");
}
}
else
{
printf("father process\n");
int fa = 0;
for(fa=1;fa>0;fa++)
{
sleep(1);
printf("father\n");
if(fa == 6)
{
alarm(3);
printf("father is alarm\n");
signal();
}
}
}
}
可重入函数
多个任务并发使用,其实就是可以被中断的代码,回来后能在原来的地方继续正常运行。但是我在使用的时候,并没有理解好该类函数的作用。留个印象即可,等之后深入的就可以回想起来
基于第二点:说明只能使用栈区
代码操作:进入函数时,首先保存此时的error的值,等该函数结束后,再恢复原值
信号集
将多个信号放在一起形成一个集合(结构体中的数组,这个数组保存的就是信号集),因此可以实现一个进程同时对多个信号进行处理(在宏观上,个人觉得)。不过信号集会与信号阻塞集联系在一起,他们可以配套使用
sigemptyset()
数据类型:sigset_t
sigfillset
理解一下功能,将信号集合设置为所有信号的集合,说明里面有所有的信号了
sigismember()
sigaddset()
sigdelset()
代码讲解
信号阻塞集
用于暂缓某一个信号的通知(传送),下面的b老师并没有直接跟a说你先讲课,我等你。而是静静的等待者,等下课了,再进去通知他,再结合前面的知识知道,b老师通知a老师去开会(信号到达),但是不一定a老师会去,这就看他对这个信号如何处理了,前面有讲过信号的处理
sigprocmask()
因此信号集与信号阻塞集一起使用
场景:将sigint(来源于Ctrl + c),添加到信号集,再把该信号集添加到阻塞集,那么我们按Ctrl + c该进程不会被退出(前提是该进程是死循环)