定时器的使用和线程安全

       在linux下如果对定时要求不太精确的话,使用alarm()和signal()就行了;

       但是如果想要实现精度较高的定时功能的话,就要使用setitimer函数。

核心api:

int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);

调用成功返回0,否则返回-1;

which为定时器类型,setitimer支持3种类型的定时器:

ITIMER_REAL: 以系统真实的时间来计算,它送出SIGALRM信号。

ITIMER_VIRTUAL: -以该进程在用户态下花费的时间来计算,它送出SIGVTALRM信号。

ITIMER_PROF: 以该进程在用户态下和内核态下所费的时间来计算,它送出SIGPROF信号。

第一个参数which指定定时器类型(上面三种之一);第二个参数是结构itimerval的一个实例;第三个参数可不做处理。

//下面这两个是八股,要用计时器setitimer()就必须先配好

struct itimerval {
struct timeval it_interval;      //it_interval指定间隔时间
struct timeval it_value;        //it_value指定初始定时时间
};


struct timeval {
long tv_sec;    //秒
long tv_usec;   //微妙
};


//如果只指定it_value,就是实现一次定时
//如果it_value和it_interval都指定,则超时后,系统会重新初始化it_value为it_interval,实现重复定时
//如果两者都清零,则会清除定时器


//tv_sec提供秒级精度,tv_usec提供微秒级精度,以值大的为先,注意1s = 1000000us = 1000ms

//ovalue用来保存先前的值,常设为NULL。

例子:

#include <stdio.h>
 #include <sys/time.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
 #include <signal.h>
 
 void call_back(int sig)
 {
     static int count = 1;
     printf("call_back : %d
", count++);
 }
 
 int main(void)
 {
     signal(SIGALRM, call_back);
     struct itimerval new_value;
     memset(&new_value, 0, sizeof(new_value));
 
     new_value.it_interval.tv_sec = 1;   //设置再次定时时间为1S
     new_value.it_interval.tv_usec = 0;
     new_value.it_value.tv_sec = 2;      //设置首次定时时间为2S
     new_value.it_value.tv_usec = 0;
 
     int ret = setitimer(ITIMER_REAL, &new_value, NULL);
     if (0 != ret)
     {
         perror("setitimer");
         exit(-1);
     }
     getchar();
 
     return 0;
 }

线程安全:

定时器死了,死循环就停不了,线程退出不了,还有就是主程序退出时,你的这个线程怎么安全退出。

还有就是实际的延时的问题,线程实际的输出时间比设定的长或者短。 

这里要特别注意一下sleep()和大写的Sleep()还有usleep()的时间单位是不同的,秒,毫秒和微秒

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值