螺纹。睡得不到1毫秒

发布于 01-23 06:58 字数 533 浏览 1 评论 0 原文

我想以不到1毫秒的速度打电话给线程睡眠。 我读到 thread.sleep 和Windows-os都不支持这一点。

解决方案是什么?

对于所有想知道我为什么需要这个的人: 我正在进行压力测试,并想知道我的模块每秒可以处理多少消息。 因此,我的代码是:

 // Set the relative part of Second hat will be allocated for each message 
 //For example: 5 messages - every message will get 200 miliseconds 
 var quantum = 1000 / numOfMessages;

 for (var i = 0; i < numOfMessages; i++)
 {
      _bus.Publish(new MyMessage());
      if (rate != 0) 
          Thread.Sleep(quantum);
 }

我很高兴能对此获得意见。

I want to call thread sleep with less than 1 millisecond.
I read that neither thread.Sleep nor Windows-OS support that.

What's the solution for that?

For all those who wonder why I need this:
I'm doing a stress test, and want to know how many messages my module can handle per second.
So my code is:

 // Set the relative part of Second hat will be allocated for each message 
 //For example: 5 messages - every message will get 200 miliseconds 
 var quantum = 1000 / numOfMessages;

 for (var i = 0; i < numOfMessages; i++)
 {
      _bus.Publish(new MyMessage());
      if (rate != 0) 
          Thread.Sleep(quantum);
 }

I'll be glad to get your opinion on that.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

护你周全 2025-01-30 06:58:33

下面的代码绝对会提供更精确的阻塞方式,而不是调用 thread.sleep(x); (尽管此方法将 block the线程,而不是放置它到睡眠)。在下面,我们使用 stopwatch 类来测量需要保持循环并阻止调用线程的时间。

using System.Diagnostics;

private static void NOP(double durationSeconds)
{
    var durationTicks = Math.Round(durationSeconds * Stopwatch.Frequency);
    var sw = Stopwatch.StartNew();

    while (sw.ElapsedTicks < durationTicks)
    {

    }
}

示例用法,

private static void Main()
{
    NOP(5); // Wait 5 seconds.

    Console.WriteLine("Hello World!");

    Console.ReadLine();
}

The code below will most definitely offer a more precise way of blocking, rather than calling Thread.Sleep(x); (although this method will block the thread, not put it to sleep). Below we are using the StopWatch class to measure how long we need to keep looping and block the calling thread.

using System.Diagnostics;

private static void NOP(double durationSeconds)
{
    var durationTicks = Math.Round(durationSeconds * Stopwatch.Frequency);
    var sw = Stopwatch.StartNew();

    while (sw.ElapsedTicks < durationTicks)
    {

    }
}

Example usage,

private static void Main()
{
    NOP(5); // Wait 5 seconds.

    Console.WriteLine("Hello World!");

    Console.ReadLine();
}
你是暖光i 2025-01-30 06:58:33

为什么?
通常,一台机器上的CPU和内核数量非常有限 - 如果独立执行单元,您只会得到一个少量。

从另一只手中,有许多过程和更多线程。每个线程都需要一些处理器时间,这是由Windows Core进程内部分配的。通常,Windows会阻止所有线程,并为特定线程提供一定数量的CPU核心时间,然后将上下文切换到其他线程。

当您调用线程时,无论您杀死窗口的整个时间范围有多小,都没有理由简单地等待它,并且上下文立即切换。下次Windows给您的线程一些CPU时,可能需要几个MS。

使用什么?
另外,您可以旋转您的CPU ,旋转不是一件可怕的事情要做,而且非常有用。例如,它在 system.collections.concurrent 中使用了很多非阻止集合的命名空间,例如:

SpinWait sw = new SpinWait();
sw.SpinOnce();

Why?
Usually there are a very limited number of CPUs and cores on one machine - you get just a small number if independent execution units.

From the other hands there are a number of processes and many more threads. Each thread requires some processor time, that is assigned internally by Windows core processes. Usually Windows blocks all threads and gives a certain amount of CPU core time to particular threads, then it switches the context to other threads.

When you call Thread.Sleep no matter how small you kill the whole time span Windows gave to the thread, as there is no reason to simply wait for it and the context is switched straight away. It can take a few ms when Windows gives your thread some CPU next time.

What to use?
Alternatively, you can spin your CPU, spinning is not a terrible thing to do and can be very useful. It is for example used in System.Collections.Concurrent namespace a lot with non-blocking collections, e.g.:

SpinWait sw = new SpinWait();
sw.SpinOnce();
那请放手 2025-01-30 06:58:33

Most of the legitimate reasons for using Thread.Sleep(1) or Thread.Sleep(0) involve fairly advanced thread synchronization techniques. Like Reed said, you will not get the desired resolution using conventional techniques. I do not know for sure what it is you are trying to accomplish, but I think I can assume that you want to cause an action to occur at 1 millisecond intervals. If that is the case then take a look at multimedia timers. They can provide resolution down to 1ms. Unfortunately, there is no API built into the .NET Framework (that I am aware of) that taps into this Windows feature. But you can use the interop layer to call directly into the Win32 APIs. There are even examples of doing this in C# out there.

宛菡 2025-01-30 06:58:33

在过去的美好时光中,您将使用Win32的“ QueryPerformanceTimer” API,当时需要进行下milisecond分辨率。

在Code-project上,似乎有更多有关该主题的信息: http:http://www。 codeproject.com/kb/cs/highperformancetimercshar.aspx

这不允许您以与Reed Copsey指出的分辨率相同的分辨率“ Sleep()”。

编辑:
正如里德·科普西(Reed Copsey)和布莱恩·吉迪恩(Brian Gideon

In the good old days, you would use the "QueryPerformanceTimer" API of Win32, when sub milisecond resolution was needed.

There seems to be more info on the subject over on Code-Project: http://www.codeproject.com/KB/cs/highperformancetimercshar.aspx

This won't allow you to "Sleep()" with the same resolution as pointed out by Reed Copsey.

Edit:
As pointed out by Reed Copsey and Brian Gideon the QueryPerfomanceTimer has been replaced by Stopwatch in .NET

ぽ尐不点ル 2025-01-30 06:58:33

我一直在寻找与OP相同的东西,并设法找到了对我有用的答案。我很惊讶其他答案都没有提到这一点。

当您调用thread.sleep()时,您可以使用两个过载之一:一个毫秒数,或timespan

Timespan的构造函数又有许多过载。 其中之一是一个长长的长度,表示时间pan代表的tick虫数量。一个tick小于1毫秒。实际上,时代文档的另一部分举例说明了1毫秒内发生10000个滴答声。

因此,我认为问题最接近的答案是,如果您想要螺纹。小于1ms的睡眠,您将创建一个timespan,timespan的价值少于1毫秒,然后将其传递给thread.sleep()。

I was looking for the same thing as the OP, and managed to find an answer that works for me. I'm surprised that none of the other answers mentioned this.

When you call Thread.Sleep(), you can use one of two overloads: An int with the number of milliseconds, or a TimeSpan.

A TimeSpan's Constructor, in turn, has a number of overloads. One of them is a single long denoting the number of ticks the TimeSpan represents. One tick is a lot less than 1ms. In fact, another part of TimeSpan's docs gave an example of 10000 ticks happening in 1ms.

Therefore, I think the closest answer to the question is that if you want Thread.Sleep for less than 1ms, you would create a TimeSpan with less than 1ms worth of ticks, then pass that to Thread.Sleep().

写给空气的情书 2025-01-30 06:58:32

你不能这样做。一个单个睡眠调用通常会比一个毫秒(依赖OS和系统依赖)阻塞更长的时间,但是根据我的经验, thread.sleep.sleep(1)倾向于阻止12-15ms之间的某个位置)。

通常,Windows并未被设计为实时操作系统。通常,这种类型的控件在正常的(桌面/服务器)版本的Windows上是不可能实现的。

您可以获得的最接近通常是旋转和吃CPU周期,直到达到想要的等待时间为止(使用高性能计数器测量)。但是,这非常糟糕 - 您会吃掉整个CPU,即使那样,您也可能会得到有时被OS抢占,有效地“睡眠”超过1ms ...

You can't do this. A single sleep call will typically block for far longer than a millisecond (it's OS and system dependent, but in my experience, Thread.Sleep(1) tends to block for somewhere between 12-15ms).

Windows, in general, is not designed as a real-time operating system. This type of control is typically impossible to achieve on normal (desktop/server) versions of Windows.

The closest you can get is typically to spin and eat CPU cycles until you've achieved the wait time you want (measured with a high performance counter). This, however, is pretty awful - you'll eat up an entire CPU, and even then, you'll likely get preempted by the OS at times and effectively "sleep" for longer than 1ms...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文