linux - Linux 中的 getrusage(RUSAGE_THREAD, ...) 和 clock_gettime(CLOCK_THREAD_CPUTIME_ID, ...) 有什么区别?

标签 linux multithreading real-time

这个问题几乎说明了一切。根据 getrusage() 的手册页,它返回:

           struct timeval ru_utime; /* user CPU time used */
           struct timeval ru_stime; /* system CPU time used */

根据 clock_gettime() 的手册页,它返回:

   CLOCK_THREAD_CPUTIME_ID (since Linux 2.6.12)
          Thread-specific CPU-time clock.

那么,(线程特定的)“用户/系统使用的 CPU 时间”与线程特定的 CPU 时间时钟有何不同?

显然,我问这个问题是因为我在移植到 Linux(来自自定义 RTOS)的应用程序中看到了两者之间的区别。该应用程序具有使用 tick()tock() 函数实现的内部分析功能。当我深入研究这个问题时,我已经将我的应用程序的一部分退化为:

tick()
// code commented out
tock()

tick() 函数记录它运行的时间,tock() 函数记录它运行的时间,计算两者之间的增量二,并报告该增量。当我使用 getrusage() 实现 tick()tock() 时,我得到的大部分是 0,偶尔有 1000us 或 10000us 值(根据我是否已将我的内核配置为 1kHz 或 100Hz 操作)。当我使用 clock_gettime() 实现 tick() & tock() 时,我得到的值以 13us 为中心(奇怪地偏移到 75us 或 100us偶尔,但我会稍后处理)。

我已经尝试在内核中启用高分辨率计时器以及 VIRT_CPU_ACCOUNTING 和/或 VIRT_CPU_ACCOUNTING_GEN 的各种组合。我看到的唯一影响是 getrusage() 报告的非零值从 1000us 变为以 1000us 为中心的一系列更高精度的值。

我终于改用 clock_gettime() 并得到了更可信的结果,但我仍然想知道为什么存在这两个系统调用,以及为什么它们的行为如此不同。所以我想我应该请教一些专家。

最佳答案

What is the difference between getrusage(RUSAGE_THREAD, …) and clock_gettime(CLOCK_THREAD_CPUTIME_ID,…) in Linux?

clock_gettime(CLOCK_THREAD_CPUTIME_ID, …) 最终调用 task_sched_runtime(p) ,它从 p->se.sum_exec_runtime 中获取计算的运行时间,其中 struct task_struct *pcurrent

getrusage(RUSAGE_THREAD, …) 调用 task_cputime_adjusted(current, &utime, &stime),其中有两个定义 [a] , [b]存在;具体使用哪一个取决于Linux内核配置项CONFIG_VIRT_CPU_ACCOUNTING_NATIVE :

Select this option to enable more accurate task and CPU time accounting.

现在我们需要知道您的内核中是否选择了这个选项。不管怎样,这两种情况看起来都与 clock_gettime() 使用的方法不同。

也就是说,我无法重现您的发现(我从两个系统调用中得到几乎相同的数字)。一个示例程序可以进一步提供帮助。

So I figured I should ask some experts.

我认为您会在 Linux 内核邮件列表中找到真正的专家。

关于linux - Linux 中的 getrusage(RUSAGE_THREAD, ...) 和 clock_gettime(CLOCK_THREAD_CPUTIME_ID, ...) 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34535641/

相关文章:

linux - 对于 Makefile 变量的每个目标

algorithm - 实时检测球的释放

c# - 对连接丢失使用react

linux - 并行执行多个 scps 时,为什么 scp 偶尔会失败?

linux - 这个终端命令到底在做什么?

java - reducer 数量对集群节点数量的依赖性

ios - 等待并发线程事件的正确方法

c# - 找出线程在 C# 中被阻塞的原因

Android fragment 相互重叠

c++ - CLOCK_THREAD_CPUTIME_ID 在 MacOS 上