gpt4 book ai didi

C++11 sleep_ 函数具有奇怪的行为

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:45:10 25 4
gpt4 key购买 nike

Here它说sleep_for “阻止当前线程的执行至少指定的 sleep_duration。”

Here它说sleep_until “阻止当前线程的执行直到指定的 sleep_time 已达到。”

因此,考虑到这一点,我只是在做我的事情,直到我注意到我的代码休眠时间比指定时间短得多。为了确保是 sleep_ 代码变得奇怪而不是让我再次编写愚蠢的代码,我创建了这个在线示例:https://ideone.com/9a9MrC(编辑行下方的代码块)当运行在线示例时,它确实做了它应该做的事情,但是在我的机器上运行完全相同的代码示例会给我这个输出:Output on Pastebin

现在我真的很困惑,想知道我的机器上的 bleep 出了什么问题。我在 Win7 x64 机器上结合使用 Code::Blocks 作为 IDE 与 This包含 GCC 4.8.2 的工具链。

*我试过了This当前版本之前的工具链,但奇怪的是,这个带有 GCC 4.8.0 的工具链甚至无法编译示例代码。

是什么导致了这种奇怪的行为?我的机器? window ?海湾合作委员会?工具链中还有其他东西吗?

附注该示例在 Here 上也可以正常工作,声明它使用 GCC 版本 4.7.2

p.p.s.使用 #include <windows.h>Sleep( 1 ); sleep 时间也比我机器上指定的 1 毫秒短很多。

编辑:示例代码:

#include <iostream>         // std::cout, std::fixed
#include <iomanip> // std::setprecision
//#include <string> // std::string
#include <chrono> // C++11 // std::chrono::steady_clock
#include <thread> // C++11 // std::this_thread

std::chrono::steady_clock timer;
auto startTime = timer.now();
auto endTime = timer.now();
auto sleepUntilTime = timer.now();

int main() {

for( int i = 0; i < 10; ++i ) {
startTime = timer.now();
sleepUntilTime = startTime + std::chrono::nanoseconds( 1000000 );
std::this_thread::sleep_until( sleepUntilTime );
endTime = timer.now();
std::cout << "Start time: " << std::chrono::duration_cast<std::chrono::nanoseconds>( startTime.time_since_epoch() ).count() << "\n";
std::cout << "End time: " << std::chrono::duration_cast<std::chrono::nanoseconds>( endTime.time_since_epoch() ).count() << "\n";
std::cout << "Sleep till: " << std::chrono::duration_cast<std::chrono::nanoseconds>( sleepUntilTime.time_since_epoch() ).count() << "\n";

std::cout << "It took: " << std::chrono::duration_cast<std::chrono::nanoseconds>( endTime - startTime ).count() << " nanoseconds. \n";
std::streamsize prec = std::cout.precision();
std::cout << std::fixed << std::setprecision(9);
std::cout << "It took: " << ( (float) std::chrono::duration_cast<std::chrono::nanoseconds>( endTime - startTime ).count() / 1000000 ) << " milliseconds. \n";
std::cout << std::setprecision( prec );
}
std::cout << "\n\n";
for( int i = 0; i < 10; ++i ) {
startTime = timer.now();
std::this_thread::sleep_for( std::chrono::nanoseconds( 1000000 ) );
endTime = timer.now();
std::cout << "Start time: " << std::chrono::duration_cast<std::chrono::nanoseconds>( startTime.time_since_epoch() ).count() << "\n";
std::cout << "End time: " << std::chrono::duration_cast<std::chrono::nanoseconds>( endTime.time_since_epoch() ).count() << "\n";

std::cout << "It took: " << std::chrono::duration_cast<std::chrono::nanoseconds>( endTime - startTime ).count() << " nanoseconds. \n";
std::streamsize prec = std::cout.precision();
std::cout << std::fixed << std::setprecision(9);
std::cout << "It took: " << ( (float) std::chrono::duration_cast<std::chrono::nanoseconds>( endTime - startTime ).count() / 1000000 ) << " milliseconds. \n";
std::cout << std::setprecision( prec );
}

return 0;
}

最佳答案

你的机器没有问题,是你的假设出了问题。

sleep 是一件非常依赖系统且不可靠的事情。通常,在大多数操作系统上,您或多或少可以保证调用 sleep 将延迟执行至少您要求的时间。 C++ 线程库必须使用操作系统提供的设施,因此您引用的 C++ 标准中的措辞。

您会注意到上一段中的措辞“或多或少保证”。首先, sleep 的方式并不是你想象的那样。它通常不会阻塞,直到计时器触发然后恢复执行。相反,它只是将线程标记为“未就绪”,并且还做了一些事情以便稍后可以撤消(这到底是什么没有定义,它可能正在设置计时器或其他东西)。
当时间到了,操作系统会再次将线程设置为“准备运行”。这并不意味着它会运行,它只意味着它是运行的候选者,只要操作系统可能受到打扰,只要 CPU 内核空闲(没有更高优先级的人想要它)。

在传统的非无滴答操作系统上,这意味着线程将可能(或更准确地说,可能)在下一个调度程序滴答时运行。也就是说,如果 CPU 完全可用。在“tickless”的更现代的操作系统(Linux 3.x 或 Windows 8)上,你更接近现实,但你仍然没有任何硬性保证。

此外,在类 Unix 系统下,sleep 可能会被信号中断,实际上等待的时间可能少于指定的时间。此外,在 Windows 下,调度程序运行的时间间隔是可配置的,更糟糕​​的是,不同的 Windows 版本表现不同 [1] [2]关于他们是向上还是向下舍休眠眠时间。
您的系统 (Windows 7) 向下舍入,所以确实是的,您实际等待的时间可能比您预期的要少。

tl;dr

sleep 是不可靠的,只是一个非常粗略的“提示”(不是必需的),表明您希望将控制权交还给操作系统一段时间

关于C++11 sleep_ 函数具有奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22863545/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com