1.1. 睡眠函数

Linux下有两个睡眠函数,原型为:

#include <unistd.h>

unsigned int sleep(unsigned int seconds);

void usleep(unsigned long usec);

函数sleep让进程睡眠seconds秒,函数usleep让进程睡眠usec微秒。

sleep睡眠函数内部是用信号机制进行处理的,用到的函数有:

#include <unistd.h>

unsigned int alarm(unsigned int seconds);

//告知自身进程,要进程在seconds秒后自动产生一个SIGALRM的信号

int pause(void); //将自身进程挂起,直到有信号发生时才从pause返回

示例:模拟睡眠3秒:

#include <signal.h>

#include <stdio.h>

#include <unistd.h>

void SignHandler(int iSignNo)

{

printf("signal:%d\n",iSignNo);

}

int main()

{

signal(SIGALRM,SignHandler);

alarm(3); //等待3秒之后自动产生SIGALRM信号

printf("Before pause().\n");

pause(); //将进程挂起,直到有信号发生才退出挂起状态

printf("After pause().\n");

return 0;

}

注意:因为sleep在内部是用alarm实现的,所以在程序中最好不要sleep与alarm混用,以免造成混乱。

1.2. 时钟处理

Linux为每个进程维护3个计时器,分别是真实计时器、虚拟计时器和实用计时器。

l 真实计时器计算的是程序运行的实际时间;

l 虚拟计时器计算的是程序运行在用户态时所消耗的时间(可认为是实际时间减掉(系统调用和程序睡眠所消耗)的时间);

l 实用计时器计算的是程序处于用户态和处于内核态所消耗的时间之和。

例如:有一程序运行,在用户态运行了5秒,在内核态运行了6秒,还睡眠了7秒,则真实计算器计算的结果是18秒,虚拟计时器计算的是5秒,实用计时器计算的是11秒。

用指定的初始间隔和重复间隔时间为进程设定好一个计时器后,该计时器就会定时地向进程发送时钟信号。3个计时器发送的时钟信号分别为:SIGALRM,SIGVTALRM和SIGPROF。

用到的函数与数据结构:

#include <sys/time.h>

1. int getitimer(int which, struct itimerval *value); //获取计时器的设置

参数which指定哪个计时器,可选项为ITIMER_REAL(真实计时器)、ITIMER_VIRTUAL(虚拟计时器、ITIMER_PROF(实用计时器))

参数value为一结构体的传出参数,用于传出该计时器的初始间隔时间和重复间隔时间

返回值:如果成功,返回0,否则-1

2. int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue); //设置计时器

参数which指定哪个计时器,可选项为ITIMER_REAL(真实计时器)、ITIMER_VITUAL(虚拟计时器、ITIMER_PROF(实用计时器))

参数value为一结构体的传入参数,指定该计时器的初始间隔时间和重复间隔时间

参数ovalue为一结构体传出参数,用于传出以前的计时器时间设置。

返回值:如果成功,返回0,否则-1

struct itimerval {

struct timeval it_interval; /* next value */ //重复间隔

struct timeval it_value; /* current value */ //初始间隔

};

struct timeval {

long tv_sec; /* seconds */ //时间的秒数部分

long tv_usec; /* microseconds */ //时间的微秒部分

};

示例:启用真实计时器的进行时钟处理(获得当前系统时间,并一秒更新一次)

#include <signal.h>

#include <time.h>

#include <sys/time.h>

#include <unistd.h>

#include <stdio.h>

#include <stdlib.h>

void sigHandler(int iSigNum)

{

time_t tt;

time(&tt);

struct tm *pTm = gmtime(&tt);

printf("%04d-%02d-%02d %02d:%02d:%02d\n", (1900+pTm->tm_year), (1+pTm->tm_mon), pTm->tm_mday, (8+pTm->tm_hour), pTm->tm_min, pTm->tm_sec);

}

void InitTime(int tv_sec, int tv_usec)

{

signal(SIGALRM, sigHandler);

struct itimerval tm;

tm.it_value.tv_sec = tv_sec;

tm.it_value.tv_usec = tv_usec;

tm.it_interval.tv_sec = tv_sec;

tm.it_interval.tv_usec = tv_usec;

if(setitimer(ITIMER_REAL, &tm, NULL) == -1)

{

perror("setitimer error");

exit(-1);

}

}

int main()

{

InitTime(1, 0);

while(1)

;

return 0;

}