Linux下用clock_gettime(CLOCK_THREAD_CPUTIME_ID, &)可获取当前线程已消耗的高精度CPU时间(用户+内核态),这是最接近“已用配额”的可观测指标;但C++标准库无“CPU时间片配额”概念,该值非调度器硬限制。

Linux下用clock_gettime(CLOCK_THREAD_CPUTIME_ID, ...)获取当前线程CPU时间
严格来说,C++标准库不提供“CPU时间片配额”这个概念——那是调度器内部的动态决策结果,用户态程序无法直接读取。但你能拿到该线程**已实际消耗的CPU时间**(即高精度用户+内核态执行时间),这是最接近“已用配额”的可观测指标。
关键点:CLOCK_THREAD_CPUTIME_ID是POSIX线程级时钟,只在Linux和部分类Unix系统支持,Windows不可用;需链接-lrt(某些旧glibc环境)。
- 必须在目标线程内调用,跨线程读不到对方的
CLOCK_THREAD_CPUTIME_ID - 返回的是
struct timespec,含秒+纳秒字段,别直接当整数打印 - 两次调用差值才是“这段代码跑了多少CPU时间”,单次值本身意义不大
#include <time.h>
#include <iostream>
struct timespec ts;
if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) == 0) {
std::cout <h3>用<code>sched_getscheduler()</code>和<code>sched_getparam()</code>查线程调度策略与优先级</h3>
<p>时间片配额由调度器策略(SCHED_FIFO、SCHED_RR、SCHED_OTHER)和nice值共同影响,但Linux的CFS(SCHED_OTHER默认)根本不固定分配时间片,而是基于虚拟运行时间动态调度。所以“配额”在这里是统计意义上的平均值,不是硬限制。</p>
<p>想看当前线程被设了什么策略和参数,得组合两个系统调用:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2823" title="C++14"><img
src="https://img.php.cn/upload/manual/001/431/639/6ac8b33c327c4749.png" alt="C++14" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="overflowclass">C++14</a>
<p class="overflowclass">C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。</p>
</div>
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<ul>
<li>
<code>sched_getscheduler(0)</code>:传0表示查当前线程,返回<code>SCHED_OTHER</code>/<code>SCHED_FIFO</code>等宏</li>
<li>
<code>sched_getparam(0, ¶m)</code>:填入<code>struct sched_param</code>,其中<code>param.sched_priority</code>对SCHED_FIFO/SCHED_RR有效,对SCHED_OTHER恒为0</li>
<li>普通用户进程默认是SCHED_OTHER + nice=0,此时<code>sched_priority</code>无意义,别误以为它是“时间片长度”</li>
</ul>
<pre class="brush:php;toolbar:false;">#include <sched.h>
int policy = sched_getscheduler(0);
struct sched_param param;
sched_getparam(0, ¶m);
std::cout <h3>为什么<code>getrusage(RUSAGE_SELF, ...)</code>里的<code>ru_stime</code>/<code>ru_utime</code>不够准</h3>
<p><code>getrusage</code>返回的<code>ru_utime</code>(用户态时间)和<code>ru_stime</code>(内核态时间)是进程级、低精度(通常微秒级)、且只在进程退出或显式调用时更新缓存——它不反映线程粒度,也不保证实时性。在多线程程序里,这些值是所有线程累加的结果,无法分离出单个线程的消耗。</p>
<ul>
<li>如果你在主线程里调用<code>getrusage</code>,看到的是整个进程从启动到此刻的总CPU时间,包括所有已结束线程</li>
<li>它不会告诉你当前线程“还剩多少配额”,因为根本不存在这个状态量</li>
<li>相比<code>clock_gettime(CLOCK_THREAD_CPUTIME_ID, ...)</code>,精度差1–2个数量级,且无法用于性能热点定位</li>
</ul>
<h3>真正影响“感觉上时间片短”的其实是CFS的<code>sysctl kernel.sched_latency_ns</code>
</h3>
<p>Linux CFS没有传统意义的时间片,但有个全局调度周期(默认6ms),它会把这周期按权重分给就绪态线程。一个线程能分到多少,取决于<code>task_struct->se.load.weight</code>,而这个权重又由<code>nice</code>值映射而来——所以调<code>setpriority(PRIO_PROCESS, 0, -5)</code>会让线程“抢”到更多CPU时间,但不是固定配额变大,而是调度器给它更高权重。</p>
<ul>
<li>修改<code>/proc/sys/kernel/sched_latency_ns</code>会影响所有CFS任务的调度粒度,但需root权限,生产环境慎改</li>
<li>普通应用不该试图“获取配额”,而应关注自身CPU时间增长是否异常(用<code>clock_gettime</code>打点对比)</li>
<li>如果你在写实时程序,必须用SCHED_FIFO/SCHED_RR并锁定内存(<code>mlockall</code>),否则即使策略设了,缺页也会导致调度延迟</li>
</ul>
<p>真正难的不是读哪个值,而是理解“时间片配额”在现代Linux里是个过时的抽象——CFS用的是完全公平调度模型,你看到的每个数字背后都是权重、虚拟时间、红黑树插入位置共同作用的结果。别信文档里“默认100ms时间片”这种说法,那是2.4内核的老黄历。</p></sched.h>
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










