Ere*_*rez 28 .net c# multithreading
我想用不到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);
}
Run Code Online (Sandbox Code Playgroud)
我很高兴得到你的意见.
Ree*_*sey 42
你不能这样做.单个睡眠调用通常会阻塞远超过一毫秒(它依赖于操作系统和系统,但根据我的经验,它Thread.Sleep(1)
往往会阻塞在12-15ms之间).
通常,Windows不是作为实时操作系统设计的.在普通(桌面/服务器)版本的Windows上,通常无法实现此类控制.
你可以得到的最接近的是旋转和吃CPU周期,直到你达到你想要的等待时间(用高性能计数器测量).然而,这非常糟糕 - 你将占用整个CPU,即便如此,你很可能会被操作系统抢占,并且有效地"睡眠"时间超过1毫秒......
Sam*_*Sam 20
下面的代码肯定会提供一种更精确的阻塞方式,而不是调用Thread.Sleep(x);
(尽管这种方法会阻塞线程,而不是让它进入休眠状态).下面我们使用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)
{
}
}
Run Code Online (Sandbox Code Playgroud)
用法示例,
private static void Main()
{
NOP(5); // Wait 5 seconds.
Console.WriteLine("Hello World!");
Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
ole*_*sii 10
为什么?
通常,一台机器上的CPU和核心数量非常有限 - 如果是独立的执行单元,您只能得到一小部分.
另一方面,有许多进程和更多线程.每个线程都需要一些处理器时间,这是由Windows核心进程在内部分配的.通常,Windows会阻塞所有线程并为特定线程提供一定量的CPU核心时间,然后将上下文切换到其他线程.
当你调用Thread.Sleep无论你杀掉Windows给线程的整个时间跨度有多小,因为没有理由等待它直接切换上下文.当Windows下次为您的线程提供一些CPU时,可能需要几毫秒.
用什么?
或者,您可以旋转您的CPU,旋转并不是一件可怕的事情,并且非常有用.例如,它在System.Collections.Concurrent命名空间中使用很多非阻塞集合,例如:
SpinWait sw = new SpinWait();
sw.SpinOnce();
Run Code Online (Sandbox Code Playgroud)
在过去,当需要亚毫秒级分辨率时,您会使用 Win32 的“QueryPerformanceTimer”API。
Code-Project 上似乎有更多关于该主题的信息:http : //www.codeproject.com/KB/cs/highperformancetimercshar.aspx
这将不允许您以 Reed Copsey 指出的相同分辨率“Sleep()”。
编辑:
正如 Reed Copsey 和 Brian Gideon 所指出的,QueryPerfomanceTimer 已被Stopwatch
.NET取代
归档时间: |
|
查看次数: |
36503 次 |
最近记录: |