为何无法用std::chrono与long long等待10^12皮秒?
问题:为什么
picoseconds_longlong(1'000'000'000'000)无法完成预期等待? 测试代码如下:
#include <chrono> #include <iostream> #include <thread> using namespace std; using picoseconds_longlong = chrono::duration<long long, std::ratio<1l, 1'000'000'000'000l>>; using picoseconds_double = chrono::duration<double, std::ratio<1l, 1'000'000'000'000l>>; int main() { cout << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now().time_since_epoch()) << endl; this_thread::sleep_for(picoseconds_longlong(1'000'000'000'000)); cout << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now().time_since_epoch()) << endl; cout << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now().time_since_epoch()) << endl; this_thread::sleep_for(picoseconds_double(1'000'000'000'000)); cout << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now().time_since_epoch()) << endl; }
运行后输出:
354170836ms 354170836ms 354170836ms 354171836ms
可见picoseconds_longlong类型的等待没有产生任何延迟,而picoseconds_double类型的等待正常完成了1秒的延迟。
原因分析
问题核心是整数类型时长转换时的溢出问题:
picoseconds_longlong是基于long long的整数型时长,传入的1'000'000'000'000等价于1秒,但sleep_for的底层实现需要将其转换为系统支持的时间单位(如纳秒、毫秒)。- 部分标准库实现处理整数型时长时,会用纯整数运算完成单位转换。若转换过程中出现中间值溢出(比如先计算
count * 源周期分子,再除以源周期分母,当count数值极大时,中间乘积可能超出整数类型的表示范围),会导致最终计算出的等待时长被错误识别为0或负数,系统直接跳过等待。 - 而
picoseconds_double是基于double的浮点型时长,转换时使用浮点运算,不会触发整数溢出,能正确表示1秒的时长,因此sleep_for可以正常工作。
内容的提问来源于stack exchange,提问作者bers
相关产品推荐
相关产品推荐

