在C语言while循环中实现定时打印变量(无需sleep函数)
无sleep的循环定时输出实现方案
核心思路是通过记录上次输出的时间戳,在每次循环迭代时检查当前时间与上次输出时间的差值,当差值达到指定间隔时执行输出操作,完全不阻塞循环的正常运行。
分平台实现示例
Linux/Unix 平台
秒级精度实现(简单版)
使用标准C库的time()函数,适合对精度要求不高的场景:
#include <stdio.h> #include <time.h> int main() { // ...初始化或其他前置操作... int calculate = 0; int x = 0; // 假设x初始值为0 const int PRINT_INTERVAL = 5; // 设定5秒输出间隔 time_t last_print_time = time(NULL); // 记录首次输出的基准时间 while(x <= 10000) { // ...这里是你对calculate的运算逻辑... calculate += x; // 示例运算,替换为你的实际代码 x++; // 检查是否到达输出时间 time_t current_time = time(NULL); if (difftime(current_time, last_print_time) >= PRINT_INTERVAL) { printf("当前calculate值: %d\n", calculate); last_print_time = current_time; // 更新基准时间 } } return 0; }
纳秒级精度实现(高精度版)
如果需要更精准的定时,使用clock_gettime()和单调时钟CLOCK_MONOTONIC(不受系统时间调整影响):
#include <stdio.h> #include <time.h> int main() { // ...初始化或其他前置操作... int calculate = 0; int x = 0; const long long PRINT_INTERVAL_NS = 5LL * 1000000000; // 5秒转纳秒 struct timespec last_print_time; clock_gettime(CLOCK_MONOTONIC, &last_print_time); // 获取单调时钟初始值 while(x <= 10000) { // ...这里是你对calculate的运算逻辑... calculate += x; x++; struct timespec current_time; clock_gettime(CLOCK_MONOTONIC, ¤t_time); // 计算时间差(纳秒) long long time_diff_ns = (current_time.tv_sec - last_print_time.tv_sec) * 1000000000LL + (current_time.tv_nsec - last_print_time.tv_nsec); if (time_diff_ns >= PRINT_INTERVAL_NS) { printf("当前calculate值: %d\n", calculate); last_print_time = current_time; // 更新基准时间 } } return 0; }
Windows 平台
使用Windows API的高精度性能计数器,避免Sleep()阻塞循环:
#include <stdio.h> #include <windows.h> int main() { // ...初始化或其他前置操作... int calculate = 0; int x = 0; const double PRINT_INTERVAL_SEC = 5.0; // 5秒输出间隔 LARGE_INTEGER perf_freq, last_perf_count, current_perf_count; QueryPerformanceFrequency(&perf_freq); // 获取性能计数器频率 QueryPerformanceCounter(&last_perf_count); // 记录初始计数 while(x <= 10000) { // ...这里是你对calculate的运算逻辑... calculate += x; x++; QueryPerformanceCounter(¤t_perf_count); // 计算已流逝的时间(秒) double elapsed_sec = (double)(current_perf_count.QuadPart - last_perf_count.QuadPart) / perf_freq.QuadPart; if (elapsed_sec >= PRINT_INTERVAL_SEC) { printf("当前calculate值: %d\n", calculate); last_perf_count = current_perf_count; // 更新基准计数 } } return 0; }
关键注意事项
- 优先选择单调时钟/计数器(如Linux的
CLOCK_MONOTONIC),避免系统时间被手动修改或NTP同步导致定时逻辑出错 - 这种轮询检查的方式不会阻塞循环,完全保证循环持续运行,仅在时间达标时执行输出
- 如果循环内的运算耗时较长,时间检查的精度依然能满足需求,无需额外优化
内容的提问来源于stack exchange,提问作者Lucas Rey
相关产品推荐
相关产品推荐

