浅析alarm信号回调函数和主循环之间存在的执行顺序
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
int alarm_count;
void sigalrm_fn(int sig)//信号回调,将打断while,执行该函数,直到退出,while才能继续执行[luther.gliethttp]
{
printf("\nalarm=%d\n", alarm_count++);
sleep(1);
alarm(1);
}
int main(void)
{
int count = 0;
time_t start;
start = time(NULL);
signal(SIGALRM, sigalrm_fn);
alarm(1);
while(1)
{
//usleep(200*1000);//极端调试方式是将该usleep注释掉
printf("%f\n"
"12345678901234567890123456789012345678901234567890123456789012345678901234567890\n"
"12345678901234567890123456789012345678901234567890123456789012345678901234567890\n"
"12345678901234567890123456789012345678901234567890123456789012345678901234567890\n"
"12345678901234567890123456789012345678901234567890123456789012345678901234567890\n"
"12345678901234567890123456789012345678901234567890123456789012345678901234567890\n"
"12345678901234567890123456789012345678901234567890123456789012345678901234567890\n"
"12345678901234567890123456789012345678901234567890123456789012345678901234567890\n",
difftime(time(NULL),start)
);
}
}
luther@gliethttp:~/arm$ ./a.out
在极限模式下
1.000000
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678
alarm=0
4567890123456789012345678901234567890123456789012345678901234567890
...
123456789012345678901234567890123456789012345678901
alarm=1
789012345678901234567890123456789012345678901234567890
3.000000
...
5.000000
1234567890123456789012345678901234567890123456789012345
alarm=2
12345678901234567890123456789012345678901234567890
...
123456789012345678901
alarm=3
890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
...
123456789012345678901234567890123456789012345678901
alarm=4
789012345678901234567890123456789012345678901234567890
9.000000
...
123456789012345678901234567890123456789012
alarm=5
01234567890123456789012345678901234567890123456789012345678901234567890
...
12345678901234567890123456789012345678901234567890123456789012345678901234567890
alarm=6
9012345678901234567890
13.000000
[可以看到问题还是比较严重的,尤其当while执行非常快时,尤其对printf函数的影响luther.gliethttp]
所以从上边的测试程序输出可以知道,alarm等signal信号回调处理函数和while()是同步执行,没有线程的概念,当检测到alarm信号发生后,
lib库调度器或者其他调度单元将立即执行sigalrm_fn信号回调函数,直到信号回调函数退出,while()才会继续从被打断点继续执行,所以这也导致alarm中全局保护变量不能与while主循环中实行同步处理机制,所以只能以pthread创建独立线程的方式来实现[luther.gliethttp].
|