C++ 获取毫秒延迟的错误值

C++ 获取毫秒延迟的错误值,c++,multithreading,visual-studio,chrono,C++,Multithreading,Visual Studio,Chrono,我试图获得1毫秒的延迟,但我得到了15倍以上。我还尝试了windowsSleep(1)函数,这也给了我同样的结果 为什么我没有得到精确的毫秒延迟 其中,当它以1秒延迟工作时 #include <iostream> #include <Windows.h> #include <thread> #include <chrono> void counter1(); auto main() -> int { std::thread p(

我试图获得1毫秒的延迟,但我得到了15倍以上。我还尝试了windows
Sleep(1)
函数,这也给了我同样的结果

为什么我没有得到精确的毫秒延迟

其中,当它以1秒延迟工作时

#include <iostream>
#include <Windows.h>
#include <thread>
#include <chrono>

void counter1();

auto main() -> int
{

    std::thread p(&counter1);
    p.join();
    return 0;
}

void counter1()
{
    int nStep = 0;
    const int STEP = 1000;
    auto start = std::chrono::high_resolution_clock::now();
    for (;;)
    {
        ++nStep; // incrementing every millisecond
        std::this_thread::sleep_for(std::chrono::milliseconds(1));
        if (nStep == STEP) {  // compares at second
            auto duration = std::chrono::high_resolution_clock::now() - start;
            std::cout << "counter took " <<
                std::chrono::duration_cast<std::chrono::seconds>(duration).count()
                << "seconds \n";
            start = std::chrono::high_resolution_clock::now();
            nStep = 0;
        }
    }
}
#包括
#包括
#包括
#包括
无效计数器1();
auto main()->int
{
标准:螺纹p(和计数器1);
p、 join();
返回0;
}
无效计数器1()
{
int nStep=0;
const int STEP=1000;
自动启动=标准::时钟::高分辨率时钟::现在();
对于(;;)
{
++nStep;//每毫秒递增一次
std::this_线程::sleep_for(std::chrono::毫秒(1));
如果(nStep==步骤){//在第二秒进行比较
自动持续时间=标准::时钟::高分辨率时钟::现在()-开始;

这是因为两件事

  • 等待不是您要做的唯一事情,增量和if语句检查也需要时间

  • 没有一个时钟是完美的


  • 另外,如果你想要一个无限循环
    ,而(true)
    看起来更好看

    你没有得到预期的结果,因为你的预期是错的。
    的睡眠不是等待确切的时间。从:

    至少为指定的线程阻止当前线程的执行 睡眠时间

    由于以下原因,此功能的阻塞时间可能超过睡眠时间 调度或资源争用延迟

    标准建议使用稳定的时钟来测量温度 如果实现使用系统时钟,则等待 时间也可能对时钟调整敏感

    准确的定时通常需要专用硬件。从台式电脑上期望1ms是相当乐观的


    <>你测量的时间不只是从<代码>睡眠> 。

    <代码>((;))< /代码>是完全标准的和完全好的-很多人认为它是优越的,甚至看到了一个编码指南强制它(但这在我看来太过火了)。;)@Aconcagua wow从未听说过它:你能提供一个链接到一些解释它优越性的文章吗?无法证明,来自15年的经验。那些投票给(;)的人认为没有明显的条件检查(承认,这是一个很糟糕的论点).请注意,无论如何,在这种情况下,优势是个人品味的问题(正如您对另一个循环的陈述看起来更好一样),从技术上讲,这两种变体只会在转换后的循环体末尾产生一个无条件分支,因此它们完全等效。谢谢@SzymonO。我知道递增和if语句需要时间,但正如我所读到的,前缀递增需要1个机器周期,让我们假设if语句需要2个cpu周期。我在处理器i7-8700CPU@3.20GHz上运行这个程序。所以我认为这个简单的程序应该不会有问题。-如果你看看这里,你也会发现相反的反对意见…我不会对
    sleep\u将CPU时间片还给操作系统感到惊讶,就像这样。在这种情况下,线程会必须等待,直到从操作系统获取下一个CPU片,这通常要比1毫秒长。如果你试图通过忙等待来避免-运气不好,线程的CPU片可能会在忙等待时正常结束,你会得到同样的效果…@Aconcagua这太棒了。它工作了。非常感谢你,但不推荐它,因为它使用的是更高功率的usag如前所述,不能保证它总是工作的。线程得到一个特定的时间,允许它们使用CPU,然后它们被抢占(即CPU被分配给另一个线程,除非线程数不超过CPU核数)。如果抢占在繁忙等待时正确发生,则您将获得相同的延迟。与以前的解决方案相比,只会减少发生这种情况的机会。