繁体   English   中英

Sleep(10)什么都不做?

[英]Sleep(10) does nothing?

我的Web服务遇到一个奇怪的情况。

这是一个简单的例子-它创建了一个持续运行的线程,在后台对磁盘进行了一些磁盘检查,并针对每个文件执行了它存在的工作后进入Sleep(10),因此它不会消耗所有CPU内核。

一切正常,直到我从RDP登录。 当我这样做时,该线程将峰值并消耗尽可能多的内存。

在这里,看看...

我有两个核心,我的前台应用使用了大约18%的CPU(这在NOW-meter上显示)。 左侧是没有登录时的CPU使用率。

到底是怎么回事? 还有更多-在这种情况下如何适当地节制线程?

在此处输入图片说明

我的代码片段产生了这个问题:

foreach (string fi in files)
{
    if (_shouldStop)
    {
        break;
    }
    lock (_workItems)
    {
        StatusString = string.Format("Examining file Dir={0}\nmask={1}\nfile={2}\nqueue={3}",
            root, mask, fi, _workItems.Count);
    }
    lock (_workItems)
    {
        if (!_workItems.Contains(fi))
        {
            if (!File.Exists(TargetForFile(fi + ".hash")))
            {
                StatusString = string.Format("Adding file Dir={0}\nmask={1}\nfile={2}\nqueue={3}",
                root, mask, fi, _workItems.Count);
                _workItems.Add(fi);
            }
        }
    }
    Thread.Sleep(10);
}

小更新:

当代码作为Windows服务运行并且没有人连接到计算机时,即使Sleep(1000)也不起作用。 我正式宣布它为WTF。

别睡觉 而是将线程优先级设置为IDLE。

接下来的事情是确定每个进程的CPU消耗,因此您不会追赶红鲱鱼。 打开Perfmom.exe并查看Process(*)\\(*)对象(所有实例)。 然后,您可以检查每个进程的“ % Processor Time和“ % User Time 并确定在关闭RDP时谁在使用18%的内存。

附带说明shuffling same directories over and over again ,为什么不shuffling same directories over and over again ,为什么不使用更改通知机制呢?

睡眠10仅为10毫秒-因此您真的接近屈服并重新开始工作。

我的猜测是,当您登录时,已经发生了足够的事情,因此您的线程不会立即被重新安排,因此它实际上最终会处于闲置状态超过10毫秒(而且我认为我读到的最大分辨率为睡眠是100米尔,顺便说一句)。 但是,当您不使用RDP时,该线程变得可用于更频繁地重新调度,因此它消耗了更多的CPU。

要进行测试,请尝试将睡眠时间增加到500(0.5秒)或1000左右,以使您有明显的睡眠时间。

另一个测试是在“什么都不做”循环中丢弃另一个线程,并在强制CPU繁忙时查看您的file.exists线程是否妥善处理。

当我登录RDP时会遇到类似的高峰,而我没有运行您的代码。 奥卡姆(Occam)的剃刀暗示它是利用内核的RDP。

此外,如果您正在执行File.Exists,无论如何线程都会在磁盘I / O上阻塞,如果有一个点给CPU带来了沉重负担,那只会在执行完之后才会出现。

最后,如果您还没有做过任何事情,例如从Normal提升进程优先级,那么它将与其他进程共享内核。 如果陷入一个紧密的循环,可能会有点不好,但是即使如此,调度程序也应该防止它自己造成太大的伤害。 如果您拥有多个内核,则对于Windows的最新版本尤其如此。

编辑:其实,全部。 为什么要自己循环轮询而不是响应FileSystemWatcher事件。 设置一个或多个FileSystemWatcher来监视感兴趣的目录,然后轮询您所关心的特定文件存在更改以作为响应。 减少代码的工作量,并且应该也具有更高的响应速度。

感谢您提供的所有答案,但我将尝试提供我自己的一个。

我现在不需要更改体系结构,并且使用任何数量的Sleep()任何尝试都将失败。 除了SO之外,我还搜索了其他一些网站,并发现Jon Skeet建议使用Monitor发出信号的一个线程。

这激发了我尝试将AutoResetEventSleep更改为WaitOne的方法,该方法仅用作睡眠的替代方法,在我的情况下,睡眠似乎不起作用。

尝试了一下,它起作用了!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM