天天看点

Linux 下获取纳秒级精度时间&使用usleep函数作为定时器&实现在特定时间点执行程序

Linux 高精度时间获取+usleep定时器使用=在特定时间点执行程序(ms级精度)

因为项目需要,我需要在多个终端(基于openwrt的AP)上同时执行某一程序,多个终端开始执行程序的时间误差需要在毫秒(ms)级及以下,在查阅了相关资料之后,我设计了相应方案,下面介绍怎样实现上述功能。

内核时间概念

  内核时间包括了几个时间:

   系统时间:自系统开始启动所经过的时间;

   墙上时间:即真实世界中所使用的时间;

   实时时钟:即RTC时间,通过硬件维持的的时间。

Linux 高精度时间获取

  函数"clock_gettime"是基于Linux C语言的时间函数,

使用格式:

  #include<time.h>

  int clock_gettime(clockid_t clk_id,struct timespec *tp);

参数clk_id指定了获取的时间类型,有如下几种:

  CLOCK_REALTIME:墙上时间,格式为:从UTC1970-1-1 0:0:0开始到当前时间经过的秒数;

  CLOCK_MONOTONIC:系统时间;

  CLOCK_PROCESS_CPUTIME_ID:本进程到当前代码系统CPU花费的时间

  CLOCK_THREAD_CPUTIME_ID:本线程到当前代码系统CPU花费的时间

struct timespec 为用于存储获取的时间结果的结构体,其格式如下:

     struct timespec

      {

        time_t tv_sec; //秒

        long tv_nsec; //纳秒

       };

Usleep函数的使用

  usleep函数能把进程挂起一段时间, 单位是微秒(千分之一毫秒)。

目标

  我的最终目标为使多个设备在系统时间的每100ms开始处同时执行某一程序,要达到这个目标,首先多个设备间的时钟应该同步,我使用GPS设备完成这一任务(见下一篇博客);其次,所有设备应在时钟刚好到达100ms倍数的时间时执行程序,例如在30.100s,30.200s,30.300s,以此达到我的目标。

我的实现代码如下

#include <time.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
	struct timespec time1 = {0, 0};   //用于保存时间
	struct timespec time2 = {0, 0};	  //用于检验程序执行效果
	int interval=0;
 while(1){
		clock_gettime(CLOCK_REALTIME, &time1);   //获取当前时间
		interval = 100000000 - time1.tv_nsec%100000000;   //计算到下一目标时刻的时间
		usleep(interval/1000);  //定时等待
		/* 此处添加需要在特定时间执行的程序,下面代码为获取执行至此处的系统时间,用于检验程序效果 */
		clock_gettime(CLOCK_REALTIME, &time2);   //
	 	printf("time2  %15ld %15ld\n",time2.tv_sec,time2.tv_nsec);
		
	}
	return 0;
}
           

下图为结果图,第二列为当前的墙上时间,单位为秒,第三列为当前的墙上时间,单位为纳秒。

可以看到,在第三列,程序在每个100ms的开始出执行,精度在数百微妙级别,从第二列可以看出,每秒程序执行了10次。

Linux 下获取纳秒级精度时间&amp;使用usleep函数作为定时器&amp;实现在特定时间点执行程序

使用或转载请注明来源。

继续阅读