Linux系统编程47 信号 - setitimer(),优先使用setitimer()计时
发布日期:2021-05-07 13:25:53 浏览次数:19 分类:精选文章

本文共 2467 字,大约阅读时间需要 8 分钟。

NAME       getitimer, setitimer - get or set value of an interval timerSYNOPSIS       #include 
int getitimer(int which, struct itimerval *curr_value); int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);

函数说明:

参数1 which

TIMER_REAL    以系统真实的时间来计算,时间到了 它送出SIGALRM信号。可以代替 alarm  ITIMER_VIRTUAL  以该进程在用户态下花费的时间来计算,它送出SIGVTALRM信号  ITIMER_PROF   以该进程在用户态下和内核态下所费的时间来计算。它送出SIGPROF信号。

相关结构体:

struct itimerval {           struct timeval it_interval; /* Interval for periodic timer */ 设置的定时器时间           struct timeval it_value;    /* Time until next expiration */ 定时器剩余时间       };       struct timeval {           time_t      tv_sec;         /* seconds */           suseconds_t tv_usec;        /* microseconds */       };

settimer工作机制是,先对it_value倒计时,当it_value为零时触发信号。然后重置为it_interval。继续对it_value倒计时。一直这样循环下去。

基于此机制。setitimer既能够用来延时运行,也可定时运行。
假如it_value为0是不会触发信号的,所以要能触发信号,it_value得大于0;假设it_interval为零,仅仅会延时。不会定时(也就是说仅仅会触发一次信号)。

参数2 new_value:

参数用来对计时器进行设置,it_interval为计时间隔,it_value为延时时长,如选择TIMER_REAL 时钟, 表示的是在setitimer方法调用成功后,延时it_value后触发一次SIGALRM信号,以后每隔it_interval触发一次SIGALRM信号。

参数3 old_value:通常用不上,设置为NULL,它是用来存储上一次setitimer调用时设置的new_value值。

On success, zero is returned. On error, -1 is returned, and errno is set appropriately

实验,流量控制之漏桶实验,用setitimer()实现

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#define BUFSIZE 10static volatile int loop = 0;static void alrm_handler(int s){ //alarm(1); loop = 1;}int main(int argc,char *argv[]){ int sfd,dfd=1; char buf[BUFSIZE]; int len,ret,pos; struct itimerval itv; if(argc < 2) { fprintf(stderr,"Usage:%s
\n",argv[0]); exit(1); } signal(SIGALRM,alrm_handler); //alarm(1); itv.it_interval.tv_sec = 1; itv.it_interval.tv_usec = 0; itv.it_value.tv_sec = 1; itv.it_value.tv_usec = 1; if(setitimer(ITIMER_REAL,&itv,NULL) < 0) { perror("setitimer()"); exit(1); } do { sfd = open(argv[1],O_RDONLY); if(sfd < 0) { if(errno != EINTR)//signal { perror("open()"); exit(1); } } }while(sfd < 0); while(1) { while(!loop) pause(); loop = 0; while((len = read(sfd,buf,BUFSIZE)) < 0) { if(errno == EINTR)//signal continue; perror("read()"); break; } if(len == 0) break; //确保写进去 len 个字节 pos = 0; while(len > 0) { ret = write(dfd,buf+pos,len); if(ret < 0) { if(errno == EINTR) //signal continue; perror("write()"); exit(1); } pos += ret; len -= ret; } } close(sfd); }
上一篇:Linux系统编程48 信号 - abort() system()
下一篇:Linux系统编程46 信号 - 流量控制,通过漏桶,令牌桶实现

发表评论

最新留言

表示我来过!
[***.240.166.169]2025年03月25日 20时49分55秒