当前位置: 首页 > news >正文

少儿英语做游戏网站推荐网上营销网站

少儿英语做游戏网站推荐,网上营销网站,东莞网上推广找谁,服装高级定制linux 时间系统 一 时间相关的系统调用 时间相关的系统调用,这里主要说明的是用来记录时间(打时间戳)和delay时间的系统调用。它们是linux时间系统的一部分。 时间相关的操作在应用层和内核层都很重要。下面的代码基于linux-4.9内核, ARCHmi…

linux 时间系统 一 时间相关的系统调用

时间相关的系统调用,这里主要说明的是用来记录时间(打时间戳)和delay时间的系统调用。它们是linux时间系统的一部分。 时间相关的操作在应用层和内核层都很重要。下面的代码基于linux-4.9内核, ARCH=mips
首先是两个比较重要的系统调用:
gettimeofday

#include <sys/time.h>
int gettimeofday(struct timeval *tv, struct timezone *tz) 
struct timeval {time_t      tv_sec;     /* seconds */suseconds_t tv_usec;    /* microseconds */};

gettimeofday系统调用是用内核vsyscall实现的。查看进程的maps, vsyscall在vdso(virtual dynamic shared object)区域。vdso区域是进程启动时内核向进程映射一段空间,这样做是为了减少某些频繁调用的系统调用的开销。

int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz)
{const union mips_vdso_data *data = get_vdso_data();struct timespec ts;int ret;ret = do_realtime(&ts, data);if (ret)return ret;if (tv) {tv->tv_sec = ts.tv_sec;tv->tv_usec = ts.tv_nsec / 1000;}if (tz) {tz->tz_minuteswest = data->tz_minuteswest;tz->tz_dsttime = data->tz_dsttime;}return 0;
}
/* do realtime 直接读取导出的realtime时间*/
static __always_inline int do_realtime(struct timespec *ts,const union mips_vdso_data *data)
{u32 start_seq;u64 ns;do {start_seq = vdso_data_read_begin(data);if (data->clock_mode == VDSO_CLOCK_NONE)return -ENOSYS;ts->tv_sec = data->xtime_sec;ns = get_ns(data);} while (vdso_data_read_retry(data, start_seq));ts->tv_nsec = 0;timespec_add_ns(ts, ns);return 0;
}

下面是vdso导出的数据区域

union mips_vdso_data {struct {/*timekeeper 维护的realtime时间*/u64 xtime_sec;  u64 xtime_nsec;/*从realtime时间向monotonic时间的偏移*/u32 wall_to_mono_sec;u32 wall_to_mono_nsec;u32 seq_count;u32 cs_shift;u8 clock_mode;u32 cs_mult;u64 cs_cycle_last;u64 cs_mask;s32 tz_minuteswest;s32 tz_dsttime;};u8 page[PAGE_SIZE];
};

clock_gettime

#include <time.h>
int clock_gettime(clockid_t clk_id, struct timespec *tp);struct timespec {time_t   tv_sec;        /* seconds */long     tv_nsec;       /* nanoseconds */};

clockid 用来指定选择哪一个clock。
内核维护两个clock

  • CLOCK_REALTIME(wall clock): 墙上时间,记录从1970-01-01 00:00:00时刻开始的时间,当进行时间同步操作的时候会被修改。当没有进行时间同步时,跟CLOCK_MONOTONIC相同
  • CLOCK_MONOTONIC: 单调递增的时间,不受修改系统时间的影响。
int __vdso_clock_gettime(clockid_t clkid, struct timespec *ts)
{const union mips_vdso_data *data = get_vdso_data();int ret;switch (clkid) {case CLOCK_REALTIME_COARSE:ret = do_realtime_coarse(ts, data);break;case CLOCK_MONOTONIC_COARSE:ret = do_monotonic_coarse(ts, data);break;case CLOCK_REALTIME:ret = do_realtime(ts, data);break;case CLOCK_MONOTONIC:ret = do_monotonic(ts, data);break;default:ret = -ENOSYS;break;}/* If we return -ENOSYS libc should fall back to a syscall. */return ret;
}

从代码中可以看出,当id是CLOCK_REALTIME时,进行的动作与gettimeofday相同。当id是CLOCK_MONOTONIC时,执行do_monotonic。

static __always_inline int do_monotonic(struct timespec *ts,const union mips_vdso_data *data)
{u32 start_seq;u64 ns;u32 to_mono_sec;u32 to_mono_nsec;do {start_seq = vdso_data_read_begin(data);if (data->clock_mode == VDSO_CLOCK_NONE)return -ENOSYS;ts->tv_sec = data->xtime_sec;ns = get_ns(data);to_mono_sec = data->wall_to_mono_sec;to_mono_nsec = data->wall_to_mono_nsec;} while (vdso_data_read_retry(data, start_seq));ts->tv_sec += to_mono_sec;ts->tv_nsec = 0;timespec_add_ns(ts, ns + to_mono_nsec);return 0;
}

do_monotonic同样是直接获取系统维护的时间xtime_sec, 但是后面要用wall_to_mono_*进行修正。
下面的例子来说明两个的区别:

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#include <time.h>const char *command = "date -s \"2018-10-24 09:00:00\"";
int main(int argc, char *argv[])
{struct timeval time_now;struct timespec time_test;struct timeval time_change;char buffer[64] = {0};gettimeofday(&time_now, NULL);strftime(buffer, 64, "Current date/time(1): %m-%d-%Y/%T", localtime(&time_now.tv_sec));printf("%s\n", buffer);printf("realtime:\n");clock_gettime(CLOCK_REALTIME, &time_test);time_change.tv_sec = time_test.tv_sec;time_change.tv_usec = time_test.tv_nsec / 1000;strftime(buffer, 64, "Current date/time(2): %m-%d-%Y/%T", localtime(&time_change.tv_sec));printf("%s\n", buffer);printf("monotonic time:\n");clock_gettime(CLOCK_MONOTONIC, &time_test);time_change.tv_sec = time_test.tv_sec;time_change.tv_usec = time_test.tv_nsec / 1000;strftime(buffer, 64, "Current date/time(3): %m-%d-%Y/%T", localtime(&time_change.tv_sec));printf("%s\n", buffer);system(command);printf("\ndate change time %s:\n\n", command);printf("time now:\n");gettimeofday(&time_now, NULL);strftime(buffer, 64, "Current date/time(1): %m-%d-%Y/%T", localtime(&time_now.tv_sec));printf("%s\n", buffer);printf("realtime:\n");clock_gettime(CLOCK_REALTIME, &time_test);time_change.tv_sec = time_test.tv_sec;time_change.tv_usec = time_test.tv_nsec / 1000;strftime(buffer, 64, "Current date/time(2): %m-%d-%Y/%T", localtime(&time_change.tv_sec));printf("%s\n", buffer);printf("monotonic time:\n");clock_gettime(CLOCK_MONOTONIC, &time_test);time_change.tv_sec = time_test.tv_sec;time_change.tv_usec = time_test.tv_nsec / 1000;strftime(buffer, 64, "Current date/time(3): %m-%d-%Y/%T", localtime(&time_change.tv_sec));printf("%s\n", buffer);return 0;
}

下边是系统刚启动一小段时间的运行结果:

/mnt # ./date_test
Current date/time(1): 01-01-1970/00:46:51
realtime:
Current date/time(2): 01-01-1970/00:46:51
monotonic time:
Current date/time(3): 01-01-1970/00:46:51
Wed Oct 24 09:00:00 UTC 2018date change time date -s "2018-10-24 09:00:00":time now:
Current date/time(1): 10-24-2018/09:00:00
realtime:
Current date/time(2): 10-24-2018/09:00:00
monotonic time:
Current date/time(3): 01-01-1970/00:46:51

修改系统时间之后,用monotonic time 转化出来的localtime依然是从启动开始的实际间隔。

http://www.lbrq.cn/news/2545327.html

相关文章:

  • 专业网站建设经费申请报告seo顾问服务 乐云践新专家
  • 专业做网站的公司有广西seo优化
  • 线上网络推广培训seo是什么牌子
  • 2019年怎么做网站今天最新新闻摘抄
  • b2b网站发布信息技巧seo作弊
  • 手机营销网站建设百度一下你就知道下
  • 企业交易平台的网站制作多少钱店铺如何运营和推广
  • 学做快餐的视频网站西安百度百科
  • 做网站需要哪些素材百度广告商
  • 网站开发报告知乎小说推广对接平台
  • dw和mysql做网站网站域名综合查询
  • 广州市疫情防控新闻发布会seo监控
  • 定制网站建设开发维护品牌软文案例
  • 春哥技术团队网站建设window优化大师
  • 网站建设合作协议模板搜索网
  • 装修网站设计图推荐找客户的十大方法
  • 保定建设环境项目网站站长工具平台
  • 软件开发工程师招聘简章沈阳关键词优化价格
  • 智慧社区背景图福州seo快速排名软件
  • 4399谁做的网站潍坊seo建站
  • 沧州网络公司电话seo云优化软件破解版
  • 网站建设价目外贸网站大全
  • 好多个人网站做经营性网站怎么申请网站
  • 网站统计插件站内seo和站外seo区别
  • 做文件的网站哪里有培训班
  • 门户网网站seo怎么做桂林seo排名
  • 黑群晖可以做网站吗b2b网站源码
  • 网站上做销售网点怎么做seo基础教程使用
  • 随州seoseo公司官网
  • 开一个做网站的公司赚钱吗电商网站建设步骤
  • Docker状况监控
  • CMake Debug/Release配置生成器表达式解析
  • GitPython08-源码解读
  • c#中switch case语句的用法
  • SpringBoot实战:高效Web开发
  • 法式基因音响品牌SK(SINGKING AUDIO)如何以硬核科技重塑专业音频版图