如何获取多线程应用程序耗时?Windows正常Linux结果偏大
解决Linux下多线程程序耗时测量偏大的问题
这种跨平台的计时差异我之前也碰到过,核心原因主要是Linux和Windows下部分计时API的语义不一样,尤其是clock(),另外两个方法如果出问题大概率是代码逻辑的小疏漏,我给你拆解分析下:
1. clock():最容易踩的坑
Linux下的clock()和Windows完全不是一回事:
- Windows的
clock()返回的是墙钟时间(从程序启动到现在的实际时间,和线程数量无关) - 但Linux的
clock()返回的是进程所有线程的CPU时间总和——简单说,如果你开了4个线程跑满CPU,那clock()的结果会是实际耗时的4倍左右,这就是你看到“大好几倍”的直接原因。
修正方案:
如果要测实际的墙钟时间(从开始到结束的真实耗时),别用clock()了,换成:
- C标准库的
clock_gettime(CLOCK_MONOTONIC, ×pec)(现代Linux无需额外链接库) - 或者直接用下面的
std::chrono方案更跨平台。
如果你的需求就是测进程总共消耗的CPU时间,那Linux下的clock()结果是准确的,只是和Windows的语义不同而已。
2. std::chrono::steady_clock::now():大概率是代码逻辑问题
steady_clock设计出来就是为了提供单调递增的墙钟时间,理论上不会出现“结果偏大几倍”的情况。你可以检查这几点:
- 是不是计时范围不对?比如
start是在某个线程启动后才记录的,或者end是在部分线程join之前就记录了?正确的姿势应该是:auto start = std::chrono::steady_clock::now(); // 启动所有线程 std::vector<std::thread> threads; for (...) { threads.emplace_back(your_task); } // 等待所有线程完成 for (auto& t : threads) { t.join(); } auto end = std::chrono::steady_clock::now(); auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start); - 有没有在计时期间做了其他CPU密集的操作?比如主线程在等线程的时候还在跑别的任务,那计时会包含这部分时间,但这属于代码逻辑的问题,不是API的锅。
3. QElapsedTimer:检查使用姿势
QElapsedTimer默认使用的是系统的单调时钟,和steady_clock类似,正常情况下结果应该和实际耗时一致。如果结果偏大,建议:
- 先做个单线程测试验证:比如
QElapsedTimer timer; timer.start(); std::this_thread::sleep_for(std::chrono::seconds(1)); qDebug() << timer.elapsed();,看输出是不是接近1000ms。如果单线程正常,那问题出在你的多线程代码逻辑上。 - 检查是不是在计时过程中意外调用了
timer.restart(),或者有没有把计时范围包含了其他无关的耗时操作。
总结
最常见的元凶就是clock()的跨平台语义差异,另外两个API如果出问题,几乎都是代码里的计时范围或线程管理的小错误。先把clock()换成墙钟时间API,再检查下join()的时机,应该就能解决问题了。
内容的提问来源于stack exchange,提问作者Ufx
相关产品推荐
相关产品推荐

