Linux时间编程

作者: konishi5202 | 来源:发表于2019-02-20 12:28 被阅读16次

    一、Linux时间类型

    在Linux系统当中,时间分为两种类型:格林威治时间和日历时间。

    Coordinated Universal Time(UTC)是世界标准的时间,即常说的格林威治标准时间(Greenwich Mean Time,GMT);UTC与GMT两者几乎是同一概念,都是指格林威治时间,只不过UTC的称呼更为正式一点。两者的区别是UTC是天文学上的概念,而GMT是基于一个原子钟。

    Calendar Time是用“一个标准时间点(如1970年1月1日0点)到此时经过的秒数”来表示的时间,即日历时间;它与格林威治时间不同。

    GMT是中央市区,北京在东8区,相差8个小时,所以北京时间=GMT时间+8小时。

    ++获取系统时间函数有:time()、gettimeofday();++

    ++设置系统时间函数有:stime()、settimeofday();++

    二、Linux时间格式

    2.1 time_t 时间类型

    time_t类型定义在time.h中:

    #ifndef __TIME_T
    #define __TIME_T
    typedef long time_t
    #endif
    

    可见,time_t实际是一个长整型。其值表示为从UTC(coordinated universal time)时间1970年1月1日00时00分00秒(也称为Linux系统的Epoch时间)到当前时刻的秒数。由于time_t类型长度的限制,它所表示的时间不能晚于2038年1月19日03时14分07秒(UTC)。为了能够表示更久远的时间,可用64位或更长的整型数来保存日历时间。

    time_t类型的时间可以通过time()函数获取。

    2.2 struct tm时间类型

    struct tm结构在time.h中定义为:

    #include <time.h>
    struct tm {
            int tm_sec;         /* seconds */
            int tm_min;         /* minutes */
            int tm_hour;        /* hours */
            int tm_mday;        /* day of the month */
            int tm_mon;         /* month */
            int tm_year;        /* year */
            int tm_wday;        /* day of the week */
            int tm_yday;        /* day in the year */
            int tm_isdst;       /* daylight saving time */
    };
    

    ANSI C标准称使用tm结构的这种时间为分解时间(broken-down time)。其成员介绍如下:

    • tm_sec:秒,取值区间为[0,59];
    • tm_min:分,取值区间为[0,59];
    • tm_hour:时,取值区间为[0,23];
    • tm_mday:日期,取值区间为[1,31];
    • tm_mon:月份,取值区间为[0,11];
    • tm_year:年份,其值为1900年至今的年数;
    • tm_wday:星期,取值区间为[0,6],0代表星期天,1代表星期一,以次类推;
    • tm_yday:从年的1月1日开始的天数,取值区间为[0,365],0代表1月1日;
    • tm_isdst:夏令时标识符,使用夏令时,tm_isdst为正;不使用夏令时,tm_isdst为0;不了解情况时,tm_isdst为负。

    使用gmtime()和localtime()可将time_t时间类型转换为struct tm结构体;

    使用mktime()可将struct tm结构体转换为time_t时间类型;

    使用asctime()将struct tm转换为字符串形式。

    2.3 struct timeval时间类型

    struct timeval结构体在sys/time.h中定义如下:

    #include <sys/time.h>
    struct timeval {
        time_t      tv_sec;     /* seconds:秒 */
        suseconds_t tv_usec;    /* microseconds:微妙 */
    };
    

    tv_sec是time_t时间类型,其值也表示为从UTC(coordinated universal time)时间1970年1月1日00时00分00秒(也称为Linux系统的Epoch时间)到当期时刻的秒数。

    设置时间函数settimeofday()与获取时间函数gettimeofday()均使用该事件类型作为参数传递。

    2.4 struct timespec时间类型

    struct timespec结构体在time.h中定义为:

    typedef long time_t;
    struct timespec {
        time_t   tv_sec;     /* seconds:秒 */
        long     tv_nsec;    /* microseconds:纳妙 */
    };
    

    它是POSIX.4标准定义的时间结构,精确度到纳秒,一般由clock_gettime(clockid_t, struct timespec *)获取特定时钟的时间。常用如下4种时钟:

    • CLOCK_REALTIME 统当前时间,从1970年1.1日算起
    • CLOCK_MONOTONIC 系统的启动时间,不能被设置
    • CLOCK_PROCESS_CPUTIME_ID 本进程运行时间
    • CLOCK_THREAD_CPUTIME_ID 本线程运行时间

    三、Linux时间编程接口

    接下来介绍的时间编程函数接口均属于Linux系统调用函数。

    3.1 time()函数

    【函数原型】:

    #include <time.h>
    time_t time(time_t *tloc);
    

    【函数说明】:

    该函数用于获取日历时间,即从1970年1月1日0点到现在所经历的秒数。参数tloc通常设置为NULL,若tloc非空,time()函数也会将返回值存到tloc指针指向的内存中。

    【返回值】:

    该函数执行成功返回秒数,失败则返回((time_t)-1)值,错误原因存于errno中。

    【使用例程】:

    #include <stdio.h>
    #include <time.h>
        
    int main(void)
    {
        time_t seconds = 0;
        
        seconds = time((time_t *)NULL);
        printf("seconds = %d\n",seconds);
        
        return 0;
    }
    

    执行结果为:

    seconds = 1434620150
    

    通常用户得到日历时间的秒数没有实际的意义,但可以为时间转化做一些辅助性质的工作。为了更好的利用时间,用户需要将这些秒数转换为更易接受的时间表示方式,这些表示时间的方式有格林威治时间、本地时间等。

    3.2 stime()函数

    【函数原型】:

    #define _SVID_SOURCE /* glibc2 needs this */
    #include <time.h>
    int stime(time_t *t);
    

    【函数说明】:

    该函数用于设置系统时间,参数t指向time_t时间格式变量,表示从UTC(coordinated universal time)时间1970年1月1日00时00分00秒(也称为Linux系统的Epoch时间)到当前时刻的秒数。

    函数执行成功返回0,失败返回-1,并将错误代码放在errno中。

    3.3 gmtime()函数

    【函数原型】:

    #include <time.h>
    struct tm *gmtime(const time_t *timep);
    struct tm *gmtime_r(const time_t *timep, struct tm *result);
    

    【函数说明】:

    该函数将time()函数获取的日历时间转化为tm结构体表示的格林威治标准时间,并保存在struct tm结构体中。参数是time()函数获取的日历时间。

    gmtime_r()是gmtime()的线程安全版本,在libc5.2.5及以后版本中可用。

    3.4 localtime()函数

    【函数原型】:

    #include <time.h>
    struct tm *localtime(const time_t *timep);
    struct tm *localtime_r(const time_t *timep, struct tm *result);
    

    【函数说明】:

    该函数将time()函数获取的日历时间转化为tm结构体表示的本地时区时间,并保存至struct tm结构体中。参数是time()函数获取的日历时间。

    localtime_r()是localtime()的线程安全版本,在libc5.2.5及以后版本中可用。

    【使用实例】:

    #include <stdio.h>
    #include <time.h>
        
    int main(void)
    {
        time_t seconds = 0;
        struct tm *utc_time = NULL;
        struct tm *local_time = NULL;
        
        seconds = time((time_t *)NULL);
        printf("seconds = %d\n",seconds);
        utc_time = gmtime(&seconds);
        printf("UTC hour is   : %d\n",utc_time->tm_hour);
        local_time = localtime(&seconds);
        printf("Local hour is : %d\n",local_time->tm_hour);
        
        return 0;
    }
    

    执行结果为:

    seconds = 1434621313
    UTC hour is : 9  //格林威治时间是9点
    Local hour is : 17 //Linux系统的当前时间是17点
    

    在命令行中执行data命令,可以看到:

    Thu Jun 18 17:59:30 CST 2015
    

    说明date命令打印的是Linux系统的本地时间。

    3.5 ctime()函数

    【函数原型】:

    #include <time.h>
    char *ctime(const time_t *timep);
    char *ctime_r(const time_t *timep, char *buf);
    

    【函数说明】:

    该函数将timep指向的日历时间(time_t时间类型)转化为本地时间的字符串形式,并返回该字符串指针,参数是time()函数返回的日历时间。

    ctime_r()是ctime()的线程安全版本,在libc5.2.5及以后版本中可用。

    【函数使用步骤】:

    使用time()获取日历时间—>使用ctime()将日历时间直接转换为本地时间字符串。

    3.6 asctime()函数

    【函数原型】:

    #include <time.h>
    time_t asctime(const struct tm *tm);
    char *asctime_r(const struct tm *tm, char *buf);
    

    【函数说明】:

    该函数将struct tm结构体时间转化为字符串形式,并返回该字符串指针,参数是gmtime()函数或localtime()函数返回的struct tm结构体时间。

    asctime_r()是asctime()的线程安全版本,在libc5.2.5及以后版本中可用。

    【函数使用步骤】:

    • 方法一:使用time()获取日历时间—>使用gmtime()将日历时间转化为格林威治时间—>使用asctime()将struct tm格式的时间转化为字符串;
    • 方法二:使用time()获取日历时间—>使用localtime()将日历时间转化为本地时间—>使用asctime()将struct tm格式的时间转化为字符串;

    【使用例程】:

    #include <stdio.h>
    #include <time.h>
        
    int main(void)
    {
        time_t t;
        char *ptr;
        struct tm *utc;
        struct tm *local;
        
        t = time((time_t *)NULL);
        printf("seconds = %d\n",t);
        ptr = ctime(&t);
        printf("Local time is : %s\n",ptr);
        utc = gmtime(&t);
        ptr = asctime(utc);
        printf("UTC time is :%s\n",ptr);
        local = localtime(&t);
        ptr = asctime(local);
        printf("Local time is :%s\n",ptr);  
        
        return 0;
    }
    

    执行结果为:

    seconds = 1434622915
    Local time is : Thu Jun 18 18:21:55 2015
    UTC time is :Thu Jun 18 10:21:55 2015
    Local time is :Thu Jun 18 18:21:55 2015
    

    在命令行终端中执行date命令,结果如下:

    Thu Jun 18 18:24:32 CST 2015
    

    3.7 mktime()函数

    【函数原型】:

    #include <time.h>
    time_t mktime(struct tm *p_tm);
    

    【函数说明】:

    该函数将p_tm指向的tm结构体时间类型转换成从1970年1月1日00时00分00秒至今的GMT时间经过的秒数。

    【函数实例】:

    #include <time.h>
    #include <stdio.h>
    int main(void)
    {
        time_t timep;
        struct tm *p_tm;
        
        timep = time((time_t *)NULL);
        printf("time():%d\n",timep);
        p_tm = local(&timep);
        timep = mktime(p_tm);
        printf("time()->localtime()->mktime():%d\n",timep);
        
        return 0;
    }
    

    3.8 difftime()函数

    【函数原型】:

    #include <time.h>
    double difftime(time_t timep1, time_t timep2);
    

    【函数说明】:

    difftime()函数比较参数timep1和timep2时间是否相同,并返回之间相差的秒数,返回类型为double。

    【使用实例】:

    #include <time.h>
    #include <stdio.h>
    int main(void)
    {
        time_t timep1,timep2;
        timep1 = time(NULL);
        sleep(2);
        timep2 = time(NULL);
        printf("The difference is %f seconds\n", difftime(timep1, timep2));
        return 0;
    }
    

    3.9 gettimeofday()函数

    【函数原型】:

    #include <sys/time.h>
    int gettimeofday(struct timeval *tv, struct timezone *tz);
    

    【函数说明】:

    该函数用于获取从UTC(coordinated universal time)时间1970年1月1日00时00分00秒(也称为Linux系统的Epoch时间)到当前时刻的时间差,并将此时间存入tv指向的结构体中,当地时区信息则放到tz指向的结构体中;该函数常用于计算耗时。函数执行成功返回0,否则返回-1,错误代码存于errno。

    【参数说明】:

    参数tv用于存放返回从UTC(coordinated universal time)时间1970年1月1日00时00分00秒(也称为Linux系统的Epoch时间)到当前时刻的时差,时间差以秒或微妙为单位;

    参数tz常设置为NULL,因为libc或glibc中并未支持tz,因此在Linux中未使用;struct timezone结构体定义如下:

    #include <sys/time.h>
    struct timezone {
        int   tz_minuteswest;  /* miniutes west of Greenwich:和GMT时间差了多少分钟 */
        int   tz_dsttime;      /* type of DST correction:日光节约时间的状态 */
    };
    

    tz_dsttime所代表的状态如下:

    DST_NONE    /* not on dst */
    DST_USA     /* USA style dst */
    DST_AUST    /* Australian style dst */
    DST_WET     /* Western European dst */
    DST_MET     /* Middle European dst */
    DST_EET     /* Eastern European dst */
    DST_CAN     /* Canada */
    DST_GB      /* Great Britain and Eire */
    DST_RUM     /* Rumania */
    DST_TUR     /* Turkey */
    DST_AUSTALT /* Australian style with shift in 1986 */
    

    【常用用法】:

    在做某件事之前调用gettimeofday(),在做完该事情之后调用gettimeofday(),两个函数的tv参数返回值的差就是该事件所消耗的时间。

    【使用实例】:

    #include <stdio.h>
    #include <sys/time.h>
        
    void function(void)
    {
        unsigned int i,j,k;
        
        for(i = 0;i < 500;i++)
            for(j = 0;j < 500;j++)
                k++;
    }
    int main(void)
    {
        time_t t;
        float timeuse;
        struct timeval tpstart,tpend;
        t = time((time_t *)NULL);
        printf("seconds is %d\n",t);
        gettimeofday(&tpstart,NULL);
        printf("seconds is %d,usec is %d\n",tpstart.tv_sec,tpstart.tv_usec);
        function();
        gettimeofday(&tpend,NULL);
        timeuse = 1000*1000*(tpend.tv_sec - tpstart.tv_sec) + tpend.tv_usec - tpstart.tv_usec;
        timeuse /= 1000*1000;
        printf("User time:%f\n",timeuse);
        
        return 0;
    }
    
    执行结果为:
    
    User time:0.000727
    

    3.10 settimeofday()函数

    【函数原型】:

    #include <sys/time.h>
    int settimeofday(const struct timeval *tv , const struct timezone *tz);
    

    【函数说明】:

    该函数把当前时间设成由tv指向的结构体数据;当tz指针不为空时,则设成tz指向的结构体数据。函数执行成功返回0,否则返回-1,错误代码存于errno。只有root权限才能使用此函数修改时间。

    3.11 strftime()函数

    【函数原型】:

    #include <time.h>
    size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);
    

    【函数说明】:

    该函数将参数tm结构的时间结构,参照参数format所指定的字符串格式做转换,转换后的字符串内容将复制到参数s所指的字符串数组中,该字符串的最大长度为参数max所控制。下面是参数format的格式指令:

    • %a:当地星期日期的名称缩写,如Sun;
    • %A:当地星期日期的名称全称,如Sunday;
    • %b:当地月份的英文缩写;
    • %h:当地月份的英文缩写;
    • %B:当地月份的名称全称;
    • %m:月份,表示法为01~12;
    • %C:以year/100表示年份;
    • %d:月里的天数,表示法为01~31;
    • %e:月里的天数,表示法为1~31;
    • %c:当地适当的日期与时间表示法表示完整时间;
    • %H:以24小时制表示小时数,表示法为00~23;
    • %k:以24小时制表示小时数,表示法为0~23;
    • %l:以12小时制表示小时数,表示法为01~12;
    • %M:分钟数,表示法为00~59;
    • %S:秒数,00~59;
    • %s:从1970年1月1日0时算起至今的UTC时间所经过的秒数;
    • %j:一年中的天数(001~366);
    • %u:一星期中的星期日期,范围1~7,星期一从1开始;
    • %U:一年中的星期数(00~53),一月第一个星期日开始为01;
    • %w:一星期中的星期日期,范围0~6,星期日从0开始;
    • %W:一年中的星期数(00~53),一月第一个星期一开始为01;
    • %p:显示对应的AM或PM;
    • %P:显示对应的am或pm;
    • %R:相当于使用“%H:%M”格式;
    • %r:相当于使用“%I:%M:%S %P”格式;
    • %D:相当于“%m%d%y”格式,如06/19/15;
    • %T:24小时时间表示,相当于“%H:%M:%S”格式;
    • %x:当地适当的日期表示年月日;
    • %X:当地适当的时间表示时分秒;
    • %y:一世纪中的年份表示;
    • %Y:完整的公元年份表示;
    • %Z:使用的时区名称;
    • %n:同\n;
    • %t:同\t;
    • %%:%符号;

    返回值复制到参数s所指的字符串数组的总字符数,不包括字符串结束符。如果返回0,表示未复制字符串到参数s内,但不表示一定有错误发生。环境变量TZ和TC_TIME会影响此函数结果。

    【使用实例】:

    #include <time.h>
    #include <stdio.h>
    #include <stdlib.h>
        
    int main(int argc, char *argv[])
    {
        char outstr[200];
        time_t t;
        struct tm *tmp;
        
        t = time(NULL);
        tmp = localtime(&t);
        if (tmp == NULL) {
            perror("localtime");
            exit(EXIT_FAILURE);
        }
        if (strftime(outstr, sizeof(outstr), argv[1], tmp) == 0) {
            fprintf(stderr, "strftime returned 0");
            exit(EXIT_FAILURE);
        }
        
        printf("Result string is \"%s\"\n", outstr);
        exit(EXIT_SUCCESS);
    } /* main */
    

    3.12 strptime()函数

    【函数原型】:

    #define _XOPEN_SOURCE /* glibc2 needs this */
    #include <time.h>
    char *strptime(const char *s, const char *format, struct tm *tm);
    

    【函数说明】:

    该函数与scanf类似,同strftime()函数相反,将一个字符串格式时间解释称为struct tm格式时间。

    【使用实例】:

    #include <stdio.h>
    #include <time.h>
        
    int main() {
        struct tm tm;
        char buf[255];
        
        strptime("2001-11-12 18:31:01", "%Y-%m-%d %H:%M:%S", &tm);
        strftime(buf, sizeof(buf), "%d %b %Y %H:%M", &tm);
        puts(buf);
        return 0;
    }
    

    3.13 clock()函数

    【函数原型】:

    #include <time.h>
    clock_t clock(void);
    

    【函数说明】:

    该函数用来返回进程所占用CPU的大约时间。

    3.14 ftime()函数

    【函数原型】:

    #include <sys/timeb.h>
    int ftime(struct timeb *tp);
    

    【函数说明】:

    该函数将日前时间日期由参数tp所指向的结构体输出,该函数无论成功还是失败都返回0。struct timep结构体定义如下:

    struct timeb{
        time_t time;  /* 从1970年1月1日0点至今的秒数 */
        unsigned short millitm;  /* 为千分之一秒 */
        short timezone; /* 为目前时区和Greenwich相差的时间,单位为妙 */
        short dstflag;  /* 为日光节约时间的修正状态,若非0为启用日光节约时间的修正 */
    };
    

    ftime()函数在4.2的BSD中支持。

    3.15 tzset()函数

    【函数原型】:

    #include <time.h>
    void tzset(void);
    extern char *tzname[2];
    extern long timezone;
    extern int daylight;
    

    【函数说明】:

    该函数将环境变量TZ设给全局变量tzname,也就是从环境变量取得目前当地的时区,时间转换函数会自动调用此函数。若TZ为设置,tzname会依照/etc/localtime找出最接近当地的时区。若TZ为NULL,或是无法判认,则使用UTC时区。此函数总是成功,并初始化tzname。

    四、Linux休眠编程接口

    有时候为了降低CPU的占用率及程序的运行速度,需要让程序休眠一段时间,在Linux应用程序中,可以使用:sleep()和usleep()函数实现。对应Linux内核中,休眠的函数有:udelay()、ndelay()、mdelay()。delay函数是忙等待,占用CPU时间,而sleep函数使调用进程休眠,并不占用CPU时间。

    4.1 sleep()函数

    【函数原型】:

    #include <unistd.h>
    unsigned int sleep(unsigned int seconds);
    

    【函数说明】:

    该函数使调用sleep()的程序休眠,直到seconds秒之后才被唤醒。该函数返回0(seconds时间到了),或返回seconds还剩余的秒数。

    4.2 usleep()函数

    【函数原型】:

    /* BSD version */
    #include <unistd.h>
    void usleep(unsigned long usec);
        
    /* SUSv2 version */
    #define _XOPEN_SOURCE 500
    #include <unistd.h>
    int usleep(useconds_t usec);
    

    【函数说明】:

    该函数使调用usleep()的程序休眠,直到usec微妙之后才被唤醒。该函数睡眠的实际时间会比usec略有延长,因为任何系统活动和时间处理调用的微处理粒度。

    该函数执行成功返回0,失败返回-1。该函数可以被信号唤醒,同时返回EINTR。

    五、Linux定时闹钟编程接口

    Linux应用程序为我们的每一个进程提供了一个定时闹钟alarm,当定时器指定的时间到时,系统会向调用进程发送SIGALARM信号,如果忽略或者不捕获此信号,则其默认动作是终止调用该alarm函数的进程;当然也可以通过signal()函数向系统注册一个自己的定时闹钟处理函数。关于信号处理方面的知识,可参照信号相关章节的内容。

    5.1 alarm()函数

    【函数原型】:

    #include <unistd.h>
    unsigned int alarm(unsigned int seconds);
    

    【函数说明】:

    alarm()函数向系统设定一个闹钟,并在闹钟时间到时内核向该进程发送SIGALRM信号。

    【注意事项】:

    • 一个进程只能有一个alarm闹钟;
    • 闹钟时间到了后,若不再次调用alarm(),将不会有新的闹钟产生;
    • 任何以seconds非0的调用,都将重新更新闹钟定时时间,并返回上一个闹钟剩余时间;若为第一次设置闹钟,则返回0;以seconds为0的调用,表示取消以前的闹钟,并将剩余时间返回。
    • 在Linux系统中提到,sleep()有可能是使用alarm()来实现的,因此,在一个进程中同时使用alarm()和sleep()并不明智。

    【使用实例】:

    #include <stdio.h>
    #include <unistd.h>
        
    int main(void)
    {
        int ret;
        sleep(3);
        ret = alarm(3);
        printf("%d\n",ret);
        pause();
        printf("This will not been print.\n");
        return 0;
    }
    

    执行结果为:

    0   //第一次为该进程设置闹钟
    Alarm clock
    

    注意最后一个printf并未打印出来,因为程序没有注册SIGALARM信号处理函数,系统默认处理动作是结束alarm()调用进程。

    5.2 setitimer()函数

    Linux系统为每个进程提供了三个独立的计时器,每个计时器在不同的时域中递减。当任何一个定时器到点了,都会向进程发送一个信号,并且重启计时器。

    【函数原型】:

    #include <sys/time.h>
    int getitimer(int which, struct itimerval *value);
    int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);
    

    【函数说明】:

    getitimer()函数获取ITIMER_REAL、ITIMER_VIRTUAL或ITIMER_PROF三个定时器中的一个的时间信息,并保存到value指向的对象中。

    setitimer()函数设置ITIMER_REAL、ITIMER_VIRTUAL或ITIMER_PROF三个定时器中的一个的定时时间为value指向的对象,若ovalue非空,则将老的时间信息保存到该对象中。

    setitimer()比alarm()功能更加强大,支持3种类型的定时器(但setitimer()并不是标准C库的函数):

    • ITIMER_REAL:以系统真实的时间来计算,它会送出SIGALRM信号;
    • ITIMER_PROF:以该进程在用户态下和内核态下所费时间来计算,它送出SIGPROF信号;
    • ITIMER_VIRTUAL:以该进程在用户态下花费的时间来计算,它送出SIGVTALRM信号;

    该函数执行成功返回0,失败返回-1,并将错误号存放在errno中。

    【参数说明】:

    witch用于指定定时器类型,其取值为上面三种之一;value是struct itimerval的一个实例;ovalue参数不做处理。struct itimerval结构体定义如下:

    struct itimerval {
        struct timeval it_interval; /* next value */
        struct timeval it_value;    /* current value */
    };
    struct timeval {
        long tv_sec;                /* seconds */
        long tv_usec;               /* microseconds */
    };
    

    it_value变量用于设置计时器的计时时间,为0时表示禁止;it_interval变量用于设置当计时器到时,重置的时间,从而实现循环定时。也就是说,计时器从it_value开始递减,当递减到0时,向进程发送一个信号,并重置定时器为it_interval,如此循环,从而可以实现循环闹钟的功能。

    【使用实例】:

    #include <stdio.h>
    #include <errno.h>
    #include <signal.h>
    #include <sys/time.h>
    void sig_func(int signo)
    {
        printf("Catch a signal.\n");
        static int realCnt = 0;
        static int virtualCnt = 0;
        switch(signo)
        {
            case SIGALRM:
                printf("The %d times:SIGALRM\n",realCnt++);
                break;
            case SIGVTALRM:
                printf("The %d times:SIGVTALRM\n",virtualCnt++);
                break;
            default:
                break;
        }
    }
    int main(void)
    {
        struct itimerval tv,tv1,otv;
        signal(SIGALRM,sig_func);
        signal(SIGVTALRM,sig_func);
        //how long to run the first time
        tv.it_value.tv_sec = 3;
        tv.it_value.tv_usec = 0;
        //after the first time,how long to run next time
        tv.it_interval.tv_sec = 2;
        tv.it_interval.tv_usec = 0;
        if(setitimer(ITIMER_REAL,&tv,&otv) != 0)
        {
            printf("setitimer err %d\n",errno);
            return -1;
        }
        tv1.it_value.tv_sec = 1;
        tv1.it_value.tv_usec = 0;
        tv1.it_interval.tv_sec = 1;
        tv1.it_interval.tv_usec = 0;
        if(setitimer(ITIMER_VIRTUAL,&tv1,&otv) != 0)
        {
            printf("setitimer err %d\n",errno);
            return -1;
        }
        while(1)
        {
            sleep(30);
            printf("otv:%d,%d,%d,%d\n",otv.it_value.tv_sec,otv.it_value.tv_usec,
                                            otv.it_interval.tv_sec,otv.it_interval.tv_usec);
        }
        return 0;
    }
    

    相关文章

      网友评论

        本文标题:Linux时间编程

        本文链接:https://www.haomeiwen.com/subject/akzcyqtx.html