写在前面:小生纯业余选手,开此博仅仅是为了积累,纯当笔记来用。如有看官光临小生博客,请不要相信我的代码就是正确的。如果您发现了错误也恳请耽误您一点时间,请您在下面指出来,不胜感激!
如果发现一些笔记的说法完全是错误的请建议我删除!
信号是很重要的,信号就是来中断一个正在执行的程序的。
可以通过kill -l命令来查询Linux定义的信号
可以通过kill -s [信号] [PID]命令来给某一个进程发送信号。
如下代码是关于atexit()的,该函数的作用是注册一个处理函数,处理函数会在main结束之后自动被调用,暂时放这儿感觉这玩意跟信号一样。
#include<stdio.h>
#include<stdlib.h>
void fun()
{
printf("run fun() over\n");
}
int main()
{
atexit(fun);
printf("Process after atexit(fun)!\n");
return 0;
}
#include<unistd.h>
#include<stdio.h>
int main()
{
printf("%d\n",getpid());
while(1)
{
printf("run\n");
sleep(1);
}
return 0;
}
通过命令kill发送一个SIGINT信号给如下进程,看看会有什么样的效果。
#include<unistd.h>
#include<stdio.h>
#include<signal.h>
#include<stdlib.h>
void handle(int s)
{
printf("Accept SIGINT \n");
exit(-1);
}
int main()
{
printf("%d\n",getpid());
signal(SIGINT,handle);
while(1)
{
printf("run\n");
sleep(1);
}
return 0;
}
以上进程搜到来自终端的SIGIN信号,该信号首先发送给内核,内核看该信号是否被某个处理函数处理在这里这个处理函数就是handle,客户程序通过signal注册信号处理函数让内核知道该信号有归宿。(纯属YY)下面是一个闹钟信号alarm
<pre name="code" class="cpp">#include<stdio.h>
#include<signal.h>
#include<sys/time.h>
#include<unistd.h>
void deal(int s)
{
printf("alarm run!\n");
sleep(2);
printf("after alarm run!\n");
}
int main()
{
signal(SIGALRM,deal);
alarm(5);
while(1)
{
printf("dead loop\n");
sleep(1);
}
return 0;
}
以上代码解释:该进程注册了一个处理SIGALRM的信号,当代码执行到alarm(5)的时候在5s之后“应该是”内核会发送一个SIGALRM的信号出来,然后内核看这个信号是否有被注册的处理函数(在该段程序中就是deal())。
这一段代码可以看出:
1.信号可以通过一个进程发送给另一个进程,信号也可以在进程内部进行发生和处理。
2.信号处理函数在执行完之后会返回到进程继续工作。
如下也是一个闹钟信号程序
#include<stdio.h>
#include<signal.h>
#include<sys/time.h>
#include<unistd.h>
void deal(int s)
{
printf("alarm run!\n");
sleep(2);
}
int main()
{
struct itimerval v = {0};
signal(SIGALRM,deal);
v.it_value.tv_sec = 3;
v.it_value.tv_usec = 1;
v.it_interval.tv_sec = 1;
setitimer(ITIMER_REAL,&v,0);
while(1)
{
printf("dead loop\n");
sleep(1);
}
return 0;
}
itimerval是一个结构体里面设置了闹钟开始的时间,同时设置了间隔多少时间后闹钟再次发送闹钟信号的时间,以上代码闹钟发送信号的时间是在程序运行3s之后,间隔1s发送一次闹钟信号。
setitimer()就是设置这种连续闹钟的一种函数。
疑问:程序开始后3s的时间是如何计算的?