gpt4 book ai didi

.NET Thread.Sleep() 随机不精确

转载 作者:行者123 更新时间:2023-12-03 12:44:24 25 4
gpt4 key购买 nike

在我的 .NET 应用程序中,我必须重放一系列传感器事件。所以我创建了一个线程来触发这些事件(通常大约每 1 - 4 毫秒)。我在这个线程中实现了一个循环并使用了 Thread.Sleep(...)使线程在事件之间休眠。

基本上它看起来像这样:

void RunThread() {
var iter = GetAllEvents().GetEnumerator();
if (!iter.MoveNext()) {
return;
}

DateTime lastEventTime = iter.Current.Timestamp;
FireEvent(iter.Current);

while (iter.MoveNext()) {
MyEvent nextEvent = iter.Current;

int timeout = (int)(nextEvent.Timestamp - lastEventTime).TotalMilliseconds;
Thread.Sleep(timeout);

FireEvent(nextEvent);
lastEventTime = nextEvent.Timestamp;
}
}

现在,我的问题是 Thread.Sleep()有时遵守指定的超时,有时不遵守。

我添加了一个检查(使用 StopWatch ,在上面的代码中不可见)关于 sleep 实际花费的时间。以下是一些结果:
Expected timeout of 1 ms but got 15 ms.
Expected timeout of 2 ms but got 13 ms.
Expected timeout of 3 ms but got 15 ms.
Expected timeout of 2 ms but got 13 ms.
Expected timeout of 1 ms but got 13 ms.
Expected timeout of 1 ms but got 15 ms.
Expected timeout of 2 ms but got 13 ms.
Expected timeout of 2 ms but got 40 ms.

为什么 Thread.Sleep()表现得“随机”?

笔记:
  • 当该线程运行时,Window 任务管理器不显示任何 CPU 使用情况。
  • 行为会随机改变,但会持续至少几秒钟。例如,有一次当我启动线程时,它确实运行良好。下一次它运行缓慢。下一次它快速运行几秒钟,而不是减慢速度或相反。

  • 更新:这是一些伪代码,显示了 Sleep行为:
    bool ChooseRespectTimeout() {
    if (this.notYetChosen) {
    this.respectTimeout = ChooseRandomly()
    this.notYetChosen = false
    reset this.notYetChosen after random time period
    }
    return this.respectTimeout
    }

    void Sleep(int timeout) {
    if (ChooseRespectTimeout())
    Thread.Sleep(timeout)
    else
    Thread.Sleep(timeout * 10)
    }

    最佳答案

    Thread.Sleep真的只是调用win32 Sleep function ,其文档详细说明了不准确之处。

    什么 Thread.Sleep确实是在指定的毫秒内放弃控制。 Sleep可能更多或更少的功能细节。操作系统交还控制权的速率由系统时间段决定,为 10-15 毫秒。所以,实际上Thread.Sleep只能精确到最近的量子。但是,正如其他人指出的那样,如果 CPU 处于重负载状态,则时间会更长。另外,如果您的线程的优先级低于所有其他线程,则它可能没有时间。

    在负载方面,它是关于可能发生切换时的负载。您正在谈论 1 毫秒的超时(正如您所看到的,由于系统量子或计时器的准确性,实际上大约是 15 毫秒)这意味着操作系统实际上只需要忙 15-30 毫秒就可以了太忙了,无法在 future 的量子之前将控制权交还给线程。这不是很多时间。如果在这 15 到 40 毫秒内有更高优先级的东西需要 CPU,则更高优先级的线程会获得时间片,这可能会使放弃控制的线程处于饥饿状态。

    什么 Thread.Sleep真正的意思是(对于大于 1 的超时值)是它告诉操作系统该线程的优先级低于系统中的每个其他线程至少在超时值内,直到线程重新获得控制权。 Thread.Sleep不是一种计时机制,而是一种放弃控制的手段。他们真的应该将“ sleep ”重命名为“产量”。

    如果你想设计一些周期性地做某事的东西,请使用计时器。如果您需要非常精确,请使用多媒体计时器。

    关于.NET Thread.Sleep() 随机不精确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12321225/

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