You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++中让程序占用指定时长的CPU时间(排除离线时间)

如何编写累计占用指定CPU时间的程序(排除离线时间)

你的问题核心是混淆了墙钟时间和CPU时间:std::chrono::high_resolution_clock统计的是从程序启动到现在的实际流逝时间(包含sleep、上下文切换等不占用CPU的离线时间),而你需要统计的是线程/进程实际占用CPU执行指令的时间。

下面分平台给出解决方案:

POSIX平台(Linux、macOS等)

使用clock_gettime函数,指定CLOCK_THREAD_CPUTIME_ID(统计当前线程的CPU时间)或CLOCK_PROCESS_CPUTIME_ID(统计整个进程的CPU时间),这些时钟只会统计线程/进程实际在CPU上运行的时间,sleep、上下文切换等离线时间不会被计入。

修改后的代码:

#include <chrono>
#include <thread>
#include <iostream>
#include <cmath>
#include <time.h>

int main() {
    struct timespec start_cpu;
    // 初始化当前线程的CPU时间起点
    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start_cpu);

    while (true) {
        struct timespec current_cpu;
        clock_gettime(CLOCK_THREAD_CPUTIME_ID, &current_cpu);

        // 计算累计占用的CPU时间(转换为秒)
        double elapsed_cpu = (current_cpu.tv_sec - start_cpu.tv_sec) + 
                             (current_cpu.tv_nsec - start_cpu.tv_nsec) / 1e9;

        if (elapsed_cpu >= 5.0) {
            break;
        }

        // 执行消耗CPU的计算任务
        volatile double d = 0;
        for (int n = 0; n < 10000; ++n) {
            d += std::sqrt(n);
        }

        std::this_thread::sleep_for(std::chrono::seconds(1));
        std::cout << "wake" << std::endl;
    }

    std::cout << "累计CPU时间已达5秒" << std::endl;
    return 0;
}

编译时需链接实时库(部分新版本GCC可省略):g++ -o cpu_time cpu_time.cpp -lrt

Windows平台

使用GetThreadTimes函数,获取线程的内核态和用户态CPU时间,两者之和就是线程实际占用的CPU时间,同样不会包含离线时间。

修改后的代码:

#include <chrono>
#include <thread>
#include <iostream>
#include <cmath>
#include <windows.h>

int main() {
    FILETIME create_time, exit_time, kernel_time, user_time;
    // 获取当前线程的初始CPU时间
    GetThreadTimes(GetCurrentThread(), &create_time, &exit_time, &kernel_time, &user_time);

    // 辅助函数:将FILETIME转换为微秒
    auto filetime_to_us = [](FILETIME ft) -> uint64_t {
        return (static_cast<uint64_t>(ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
    };

    uint64_t start_cpu = filetime_to_us(kernel_time) + filetime_to_us(user_time);

    while (true) {
        GetThreadTimes(GetCurrentThread(), &create_time, &exit_time, &kernel_time, &user_time);
        uint64_t current_cpu = filetime_to_us(kernel_time) + filetime_to_us(user_time);

        // 计算累计CPU时间(FILETIME单位是100纳秒,转换为秒)
        double elapsed_cpu = (current_cpu - start_cpu) / 1e6;

        if (elapsed_cpu >= 5.0) {
            break;
        }

        // 消耗CPU的计算任务
        volatile double d = 0;
        for (int n = 0; n < 10000; ++n) {
            d += std::sqrt(n);
        }

        std::this_thread::sleep_for(std::chrono::seconds(1));
        std::cout << "wake" << std::endl;
    }

    std::cout << "累计CPU时间已达5秒" << std::endl;
    return 0;
}

核心逻辑说明

  • 不管是主动调用sleep让出CPU,还是被动被操作系统上下文切换,这些时间段内线程并未占用CPU执行指令,所以对应的CPU时间统计不会增加
  • 只有当线程在执行计算任务时,CPU时间才会累计,直到达到你设定的5秒配额

内容的提问来源于stack exchange,提问作者Frontier_Setter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 05:15:58