Thread.Sleep(1) 在 C# 中有什么影响?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/508208/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the impact of Thread.Sleep(1) in C#?
提问by Justin Tanner
In a windows form application what is the impact of calling Thread.Sleep(1)
as illustrated in the following code:
在 Windows 窗体应用程序中,调用的影响是什么,Thread.Sleep(1)
如以下代码所示:
public Constructor()
{
Thread thread = new Thread(Task);
thread.IsBackground = true;
thread.Start();
}
private void Task()
{
while (true)
{
// do something
Thread.Sleep(1);
}
}
Will this thread hog all of the available CPU?
这个线程会占用所有可用的 CPU 吗?
What profiling techniques can I use to measure this Thread's CPU usage ( other than task manager )?
我可以使用哪些分析技术来测量此线程的 CPU 使用率(任务管理器除外)?
采纳答案by Bob Nadler
As stated, your loop will not hog the CPU.
如上所述,您的循环不会占用 CPU。
But beware: Windows is nota real-time OS, so you will notget 1000 wakes per second from Thread.Sleep(1). If you haven't used timeBeginPeriodto set your minimum resolution you'll wake about every 15 ms. Even after you've set the minimum resolution to 1 ms, you'll still only wake up every 3-4 ms.
但请注意:Windows不是实时操作系统,因此您不会从 Thread.Sleep(1) 获得每秒 1000 次唤醒。如果您没有使用timeBeginPeriod设置您的最小分辨率,您将每 15 毫秒唤醒一次。即使您将最小分辨率设置为 1 毫秒,您仍然只能每 3-4 毫秒唤醒一次。
In order to get millisecond level timer granularity you have to use the Win32 multimedia timer (C# wrapper).
为了获得毫秒级计时器粒度,您必须使用 Win32 多媒体计时器(C# 包装器)。
回答by Frederick The Fool
No it won't hog the CPU, it will just pause your thread for at leastthat long. While your thread is paused, the operating system can schedule another, unrelated thread to make use of the processor.
不,它不会占用 CPU,它只会暂停您的线程至少那么长时间。当您的线程暂停时,操作系统可以安排另一个不相关的线程来使用处理器。
回答by TheSmurf
No, it won't hog all available CPU, because a sleeping thread will be switched out by the OS' scheduler when another thread has work to do.
不,它不会占用所有可用的 CPU,因为当另一个线程有工作要做时,操作系统的调度程序将关闭一个睡眠线程。
回答by krosenvold
No, it will not. You'll barely see it. Somewhere less than 1000 times a second this thread will wake up and do next to nothing before sleeping again.
不,不会。你几乎看不到它。在每秒不到 1000 次的某个地方,这个线程会醒来,在再次睡觉之前几乎什么都不做。
Edit:
编辑:
I had to check. Running on Java 1.5 , this test
我不得不检查。在 Java 1.5 上运行,此测试
@Test
public void testSpeed() throws InterruptedException {
long currentTime = System.currentTimeMillis();
int i = 0;
while (i < 1000)
{
Thread.sleep(1);
i++;
}
System.out.println("Executed in " + (System.currentTimeMillis() - currentTime));
}
Ran at approximately 500 sleeps per second on my 3ghz machine. I suppose C# should be fairly much the same. I assume someone will report back with C# numbers for this intensely important real-world benchmark. There was no observable CPU usage, by the way.
在我的 3ghz 机器上以每秒大约 500 个睡眠的速度运行。我想 C# 应该大致相同。我假设有人会为这个非常重要的现实世界基准报告 C# 数字。顺便说一下,没有可观察到的 CPU 使用率。
回答by Andrei R?nea
A thread can at most hog one (logical) CPU at a time. And a 1ms sleep will not be hogging. Don't sweat it.
一个线程一次最多可以占用一个(逻辑)CPU。并且 1 毫秒的睡眠不会占用大量资源。不要出汗。
回答by Jorge Córdoba
Thread.Sleep(1) as stated will not hog the CPU.
Thread.Sleep(1) 如上所述不会占用 CPU。
Here is what happens when a thread sleeps (more or less):
以下是线程休眠(或多或少)时发生的情况:
- Thread.Sleep is translated into a system call, which in turn triggers a trap (an interruption that allows the operating system to take control)
- The operating system detects the call to sleep and marks your thread as blocked.
- Internally the OS keeps a list of threads that need to be waken up and when it should happen.
- Since the thread is no longer using the CPU the OS...
- If the parent process has not used up all of its time slice the OS will schedule another thread of the process for execution.
- Otherwise another process (or the idle process) will start executing.
- When the time is due, your thread will be scheduled again for execution, that doesn't mean it will start executing automatically.
- Thread.Sleep 被翻译成系统调用,进而触发陷阱(允许操作系统控制的中断)
- 操作系统检测到睡眠调用并将您的线程标记为阻塞。
- 操作系统在内部保存了一个需要唤醒的线程列表以及它应该何时发生。
- 由于线程不再使用 CPU,操作系统...
- 如果父进程没有用完它的所有时间片,操作系统将调度进程的另一个线程来执行。
- 否则另一个进程(或空闲进程)将开始执行。
- 当时间到期时,您的线程将再次被安排执行,这并不意味着它会自动开始执行。
On a final note, I don't exactly know what you are doing but it would seem you're trying to take the role of the scheduler, that is, sleeping to provide the CPU with time to do other things...
最后一点,我不完全知道你在做什么,但看起来你正在尝试扮演调度程序的角色,也就是说,睡眠为 CPU 提供时间做其他事情......
In a few cases (very few indeed) it might be all right, but mostly you should let the scheduler do its work, it probably knows more than you do, and can make the work better than you can do it.
在少数情况下(确实很少)它可能没问题,但大多数情况下你应该让调度程序完成它的工作,它可能比你知道的更多,并且可以使工作比你做的更好。
回答by Justin Tanner
As Bob Nadler mentioned Thread.Sleep(1)
does not guarantee a sleep time of 1ms.
正如 Bob Nadler 所提到的Thread.Sleep(1)
,不保证 1ms 的睡眠时间。
Here is an example using the Win32 multimedia timer to force a sleep of 1ms.
下面是一个使用 Win32 多媒体计时器强制休眠 1 毫秒的示例。
[DllImport("winmm.dll")]
internal static extern uint timeBeginPeriod(uint period);
[DllImport("winmm.dll")]
internal static extern uint timeEndPeriod(uint period);
timeBeginPeriod(1);
while(true)
{
Thread.Sleep(1); // will sleep 1ms every time
}
timeEndPeriod(1);
Testing this in a C# GUI application, I found that the application used about 50% of my CPU.
在 C# GUI 应用程序中对此进行测试,我发现该应用程序使用了大约 50% 的 CPU。
For more discussion on this topic see the following forum thread:
有关此主题的更多讨论,请参阅以下论坛主题:
回答by Bengie
This is an old thread that comes up in a lot of my searches, but Win7 has a new scheduler and seems to behave differently than the above.
这是一个旧线程,在我的很多搜索中都会出现,但 Win7 有一个新的调度程序,并且其行为似乎与上述不同。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
DateTime dtEnd = DateTime.Now.AddSeconds(1.0);
int i = 0;
while (DateTime.Now < dtEnd)
{
i++;
Thread.Sleep(1);
}
Console.WriteLine(i.ToString());
i = 0;
long lStart = DateTime.Now.Ticks;
while (i++ < 1000)
Thread.Sleep(1);
long lTmp = (DateTime.Now.Ticks - lStart) / 10000;
Console.WriteLine(lTmp.ToString());
Console.Read();
}
}
}
With the above code, My first result gave 946. So in the timespan of 1 second using 1ms sleeps, I got 946 wake ups. That's very close to 1ms.
使用上面的代码,我的第一个结果给出了 946。所以在使用 1ms 睡眠的 1 秒时间跨度内,我得到了 946 次唤醒。这非常接近 1ms。
The second part asks how long it takes to do 1000 sleep events at 1ms each. I got 1034ms. Again, nearly 1ms.
第二部分询问以 1ms 为单位执行 1000 个睡眠事件需要多长时间。我得到了 1034 毫秒。同样,将近1ms。
This was on a 1.8ghz core2duo + Win7 using .Net 4.0
这是在使用 .Net 4.0 的 1.8ghz core2duo + Win7 上
Edit: remember, sleep(x) doesn't mean wake up up at this time, it means wake me up no earlier than this time. It is not guaranteed. Although, you can increase the priority of the thread and Windows should schedule your thread before lower priority threads.
编辑:记住,sleep(x) 并不意味着此时醒来,它意味着不早于这个时间唤醒我。不能保证。虽然,您可以增加线程的优先级,并且 Windows 应该在较低优先级的线程之前安排您的线程。
回答by FrankyHollywood
also have a look at this: msdn forum
也看看这个:msdn论坛
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
namespace Test
{
public static class Program
{
public static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
for (int i = 0; i < 10; ++i)
{
sw.Reset();
sw.Start();
Thread.Sleep(50);
sw.Stop();
Console.WriteLine("(default) Slept for " + sw.ElapsedMilliseconds);
TimeBeginPeriod(1);
sw.Reset();
sw.Start();
Thread.Sleep(50);
sw.Stop();
TimeEndPeriod(1);
Console.WriteLine("(highres) Slept for " + sw.ElapsedMilliseconds + "\n");
}
}
[DllImport("winmm.dll", EntryPoint="timeBeginPeriod", SetLastError=true)]
private static extern uint TimeBeginPeriod(uint uMilliseconds);
[DllImport("winmm.dll", EntryPoint="timeEndPeriod", SetLastError=true)]
private static extern uint TimeEndPeriod(uint uMilliseconds);
}
}
回答by Xan
Small sleep times should be avoided as a thread giving up its time slice gets a priority boost when resignaled, and that can lead to high context switches. In a multithreaded / server application, this can lead to a thrashing effect as the threads are battling for CPU time. Instead, rely on asynchronous functions and synchronization objects such as critical sections or mutexes / semaphores.
应该避免小的睡眠时间,因为放弃其时间片的线程在重新发出信号时会获得优先级提升,这可能导致高上下文切换。在多线程/服务器应用程序中,这可能会导致抖动效果,因为线程正在争夺 CPU 时间。相反,依靠异步函数和同步对象,例如临界区或互斥体/信号量。