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

嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间

目录

1 进程时间概念

2 times 函数

2.1 times 函数介绍

2.2 示例程序

3 clock 函数

3.1 clock 函数介绍

3.2 示例程序


1 进程时间概念

进程时间指的是进程从创建后(也就是程序运行后)到目前为止这段时间内使用 CPU 资源的时间总数,出于记录的目的,内核把 CPU 时间(进程时间) 分为以下两个部分:

  • 用户 CPU 时间:进程在用户空间(用户态)下运行所花费的 CPU 时间。有时也成为虚拟时间(virtual time)。
  • 系统 CPU 时间:进程在内核空间(内核态)下运行所花费的 CPU 时间。这是内核执行系统调用或代表进程执行的其它任务(譬如,服务页错误)所花费的时间。

一般来说,进程时间指的是用户 CPU 时间和系统 CPU 时间的总和,也就是总的 CPU 时间

Tips:进程时间不等于程序的整个生命周期所消耗的时间, 如果进程一直处于休眠状态(进程被挂起、不会得到系统调度),那么它并不会使用 CPU 资源,所以休眠的这段时间并不计算在进程时间中。

2 times 函数

2.1 times 函数介绍

times函数是用来获取进程占用CPU的时间信息的,函数返回自进程启动以来,在用户模式和内核模式下消耗的CPU时间。times函数的原型定义在sys/times.h头文件中,其定义如下: 

#include <sys/times.h>clock_t times(struct tms *buf);
  • buf:times()会将当前进程时间信息存在一个 struct tms 结构体数据中,其定义如下:
struct tms {clock_t tms_utime;  // 用户模式下的CPU时间clock_t tms_stime;  // 内核模式下的CPU时间clock_t tms_cutime; // 子进程在用户模式下的CPU时间clock_t tms_cstime; // 子进程在内核模式下的CPU时间
};

返回值: 返回值类型为 clock_t(实质是 long 类型), 调用成功情况下,将返回从过去任意的一个时间点(譬如系统启动时间) 所经过的时钟滴答数(其实就是系统节拍数), 将(节拍数 / 节拍率)便可得到秒数,返回值可能会超过 clock_t 所能表示的范围(溢出); 调用失败返回-1,并设置 errno。

2.2 示例程序

下面的程序通过 times()来计算程序中某一段代码执行所耗费的进程时间和总的时间,测试程序如下所示:

#include <stdio.h>
#include <sys/times.h>
#include <unistd.h>
#include <time.h>int main() {struct timespec start, end;clock_t start_clk_t, end_clk_t;struct tms start_tms, end_tms;long clock_ticks;int i;// 获取系统时钟的滴答数clock_ticks = sysconf(_SC_CLK_TCK);// 记录开始时间(CPU时间和实际时间)times(&start_tms);clock_gettime(CLOCK_MONOTONIC, &start);// 模拟一些工作,例如循环for (i = 0; i < 1000000; i++) {// 这里可以放置一些计算操作,比如 i * i}// 记录结束时间(CPU时间和实际时间)times(&end_tms);clock_gettime(CLOCK_MONOTONIC, &end);// 计算CPU时间差(用户模式和内核模式)clock_t total_utime = end_tms.tms_utime - start_tms.tms_utime;clock_t total_stime = end_tms.tms_stime - start_tms.tms_stime;// 计算实际运行时间差(秒和纳秒)long seconds = end.tv_sec - start.tv_sec;long nanoseconds = end.tv_nsec - start.tv_nsec;// 打印结果printf("User mode CPU time used: %ld seconds\n", total_utime / clock_ticks);printf("Kernel mode CPU time used: %ld seconds\n", total_stime / clock_ticks);printf("Real time used: %ld seconds and %ld nanoseconds\n", seconds, nanoseconds);return 0;
}

程序中使用 sysconf(_SC_CLK_TCK)获取到系统节拍率,程序还使用了一个库函数 sleep()模拟程序运行,可以看到用户 CPU 时间为 1.9 秒,系统 CPU 时间为 0 秒,也就是说测试的这段代码并没有进入内核态运行,所以总的进程时间 = 用户 CPU 时间 + 系统 CPU 时间 = 1.9 秒。运行结果如下:

3 clock 函数

3.1 clock 函数介绍

clock函数是用来获取程序的CPU时间(也就是进程时间)。函数返回自程序启动以来,程序所占用的CPU时间总量,包括用户模式和内核模式下的时间。clock函数的原型定义在time.h头文件中,其定义如下: 

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

注意:clock()函数虽然可以很方便的获取总的进程时间,但并不能获取到单独的用户 CPU 时间和系统 CPU 时间,在实际编程当中,根据自己的需要选择。

3.2 示例程序

下面是一个使用clock函数的简单示例:

#include <stdio.h>
#include <time.h>int main() {clock_t start, end;double cpu_time_used;int i, j;start = clock(); // 记录开始时间for (i = 0; i < 20000; i++)for (j = 0; j < 20000; j++); // 空操作,用于消耗CPU时间end = clock(); // 记录结束时间// 计算CPU时间使用量(秒)cpu_time_used = (double)(end - start) / CLOCKS_PER_SEC;printf("CPU time used: %f seconds\n", cpu_time_used);return 0;
}

程序首先记录了程序开始时的CPU时间,然后执行了一些操作,接着记录了结束时的CPU时间。通过计算这两个时间的差值,我们得到了程序占用CPU的总时间,并将其转换为秒。程序运行结果如下:

相关文章:

  • 量化交易对长期投资的影响
  • 【matlab】回归预测——智能优化算法支持向量机
  • Java中继承接口和实现接口的区别、接口和抽象类的区别、并理解关键字interface、implements
  • centos7.9 python3环境(virtualenv)搭建及所遇错误
  • 2024年洗地机哪个牌子好?内行人最建议这4个:清洁力口碑公认都不错
  • 【MySQL】事务实现原理
  • Pip换源,以及python解耦方法实现
  • Linux/Ubuntu访问局域网共享文件夹
  • 面向物联网行业的异常监控追踪技术解决方案:技术革新与运维保障
  • 【C语言】C语言 4 个编译过程详解
  • 一站式采购!麒麟信安CentOS安全加固套件上架华为云云商店
  • 简易电阻、电容和电感测量仪-FPGA
  • [leetcode]max-consecutive-ones 最大连续1的个数
  • 【高级篇】第10章 Elasticsearch 集群管理与扩展
  • 数据结构(Java):迭代器遍历【底层源码解析】
  • JavaScript 如何正确处理 Unicode 编码问题!
  • [deviceone开发]-do_Webview的基本示例
  • 2017前端实习生面试总结
  • 2019年如何成为全栈工程师?
  • create-react-app项目添加less配置
  • java架构面试锦集:开源框架+并发+数据结构+大企必备面试题
  • mysql innodb 索引使用指南
  • MySQL数据库运维之数据恢复
  • PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • SQLServer之创建显式事务
  • 多线程事务回滚
  • 区块链技术特点之去中心化特性
  • 如何用vue打造一个移动端音乐播放器
  • hi-nginx-1.3.4编译安装
  • # Maven错误Error executing Maven
  • $GOPATH/go.mod exists but should not goland
  • (3) cmake编译多个cpp文件
  • (Python) SOAP Web Service (HTTP POST)
  • (没学懂,待填坑)【动态规划】数位动态规划
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (轉)JSON.stringify 语法实例讲解
  • (轉貼) 資訊相關科系畢業的學生,未來會是什麼樣子?(Misc)
  • ..thread“main“ com.fasterxml.jackson.databind.JsonMappingException: Jackson version is too old 2.3.1
  • .[backups@airmail.cc].faust勒索病毒的最新威胁:如何恢复您的数据?
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .net core 6 redis操作类
  • .net mvc部分视图
  • .Net 应用中使用dot trace进行性能诊断
  • .netcore 6.0/7.0项目迁移至.netcore 8.0 注意事项
  • .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)
  • .Net面试题4
  • .NET下ASPX编程的几个小问题
  • .NET运行机制
  • /etc/sudoers (root权限管理)
  • [ C++ ] STL priority_queue(优先级队列)使用及其底层模拟实现,容器适配器,deque(双端队列)原理了解
  • [ C++ ] STL_stack(栈)queue(队列)使用及其重要接口模拟实现
  • [ vulhub漏洞复现篇 ] JBOSS AS 4.x以下反序列化远程代码执行漏洞CVE-2017-7504
  • [.NET 即时通信SignalR] 认识SignalR (一)