1 alarm函数
该函数是设置定时器的函数,每个进程都有且只有唯一个定时器。并且定时与进程状态无关(自然定时法),例如就绪、运行、挂起(阻塞、暂停)、终止、僵尸…无论进程处于何种状态,alarm都计时。
unsigned int alarm(unsigned int seconds);
/*
功能:设置定时器(闹钟),在指定seconds后,内核会给当前进程发送编号为14的SIGALRM信号,进程收到该信号,默认动作终止。若时间未到,返回剩余的秒数,若时间到了或者超了返回0,无失败返回。
需要注意一点的是:当我们调用alarm(0)时,它的意思是取消定时器。例如:
alarm(5); //5秒后发送信号
alarm(0): //取消上面的信号,5秒后不再发送信号.
*/
例如举个小例子。
当alarm(5)调用后经过3s,alarm(4)再调用会返回2s,此时定时器重设为4。再经过5s后,因为超时了所以返回0,并且发送信号给当前线程,默认动作终止进程。所以进程终止了。但是我们假设没有终止,还是继续分析的话,alarm(0)后,定时器终止,信号不再发送。当然注意,这是我们的假设,实际程序会被终止。
alarm(5) → 3sec → alarm(4) → 5sec → alarm(5) → alarm(0)
2 alarm案例
编写程序,测试你使用的计算机1秒钟能数多少个数。
#include <stdio.h>
#include <unistd.h>
int main(void)
{
int i;
alarm(1);
for(i = 0; ; i++)
printf("%d\n", i);
return 0;
}
结果大概88736。与硬件相关。
当然我们可以使用命令time去查看程序的运行时间。执行命令:
time ./alarm //参2为可执行程序
看下图,real为真实的运行时间,user为用户使用的时间(用户区),sys为系统时间(内核),实际上还有一个等待时间并未列出。
一个程序的运行时长有这样的公式:
实际执行时间 = 系统时间 + 用户时间 + 等待时间
所以我们可以推算出等待的时间大概是0.8s左右。并且等待时间一般是重定向,打印例如printf等等。所以程序运行的瓶颈在于IO,优化程序,首选优化IO,即少点输入输出,而打印就是输出的一种。