1.使用14号信号SIGALRM,调用alarm函数
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
void handle(int signum)
{
printf("hello\n");
}
int main(int argc, const char *argv[])
{
signal(SIGALRM, handle);
while(1)
{
alarm(3);
sleep(3);
}
return 0;
}
//每隔3秒向自身发送一个SIGALRM信号,signal收到 SIGALRM信号后调用handle进行处理
--》alarm只能精确到秒
2.setitimer -->也是通过向自身发送信号进行处理的,不过可以精确到毫妙级别
int setitimer(int which, const struct itimerval *new_value,
struct itimerval *old_value);
ITIMER_REAL decrements in real time, and delivers SIGALRM upon expiration.
ITIMER_VIRTUAL decrements only when the process is executing, and delivers
SIGVTALRM upon expiration.
ITIMER_PROF decrements both when the process executes and when the system is
executing on behalf of the process. Coupled with ITIMER_VIR-
TUAL, this timer is usually used to profile the time spent by
the application in user and kernel space. SIGPROF is delivered
upon expiration.
struct itimerval {
struct timeval it_interval; /* next value */
struct timeval it_value; /* current value */
};
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
--》3种模式产生3中不同的信号,使用方法类似
在该例子中,每隔一秒发出一个SIGALRM,每隔0.5秒发出一个SIGVTALRM信号:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
int sec;
void sigroutine(int signo){
switch (signo){
case SIGALRM:
printf("Catch a signal -- SIGALRM \n");
signal(SIGALRM, sigroutine);
break;
case SIGVTALRM:
printf("Catch a signal -- SIGVTALRM \n");
signal(SIGVTALRM, sigroutine);
break;
}
fflush(stdout);
return;
}
int main()
{
struct itimerval value, ovalue, value2; //(1)
sec = 5;
printf("process id is %d\n", getpid());
signal(SIGALRM, sigroutine);
signal(SIGVTALRM, sigroutine);
value.it_value.tv_sec = 1;
value.it_value.tv_usec = 0;
value.it_interval.tv_sec = 1;
value.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &value, &ovalue); //(2)
value2.it_value.tv_sec = 0;
value2.it_value.tv_usec = 500000;
value2.it_interval.tv_sec = 0;
value2.it_interval.tv_usec = 500000;
setitimer(ITIMER_VIRTUAL, &value2, &ovalue);
for(;;)
;
}
3.timerfd_create timerfd_settime -->通过时间设置fd可读,然后通过select轮询,调用处理函数
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/timerfd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#define ERR_EXIT(m) \
do { \
perror(m);\
exit(EXIT_FAILURE);\
}while(0)
int main(int argc, const char *argv[])
{
struct itimerspec time;
time.it_value.tv_sec = 5;
time.it_interval.tv_sec = 2;
int timerfd = timerfd_create(CLOCK_REALTIME, 0);
if(timerfd == -1)
ERR_EXIT("timerfd_create");
if(timerfd_settime(timerfd, 0, &time, NULL) == -1)
ERR_EXIT("timerfd_settime");
fd_set read1, ready;
FD_ZERO(&read1);
FD_SET(timerfd, &read1);
char buf[1024];
struct timeval time_select;
while(1)
{
time_select.tv_sec = 3;//必须定义在while内部
time_select.tv_usec = 11;
ready = read1;
int nready = select(timerfd + 1, &ready, NULL, NULL, &time_select);//设置为一直阻塞
if(nready == -1)
ERR_EXIT("select");
else if(nready == 0)
printf("timeout");
else
{
if(-1 == read(timerfd, buf, sizeof buf))
{
printf("%s\n", strerror(errno));//打印错误信息
ERR_EXIT("read");
}
printf("come\n");
}
}
return 0;
}
4.直接使用select -->精确到毫秒级别
int msSleep(long ms) {
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = ms;
return select(0, NULL, NULL, NULL, &tv);
}
其他资料:
http://www.cppblog.com/CppExplore/archive/2008/04/02/46111.html