代码之家  ›  专栏  ›  技术社区  ›  James Dunne

.NET应用程序中需要微秒延迟来限制UDP多播传输速率

  •  7
  • James Dunne  · 技术社区  · 15 年前

    我正在用C语言编写一个UDP多播客户机/服务器对,我需要一个50-100微秒(微秒)的延迟来限制服务器传输速率。这有助于避免严重的数据包丢失,也有助于防止磁盘I/O绑定的客户机过载。请不要推荐thread.sleep或thread.spinwait。我不会问我是否需要这些。

    我的第一个想法是使用某种高性能计数器,并执行一个简单的while()循环来检查经过的时间,但是我想避免这种情况,因为它感觉很笨拙。这是否也会影响服务器进程的CPU利用率?

    跨平台解决方案的奖励积分,即不特定于Windows。提前谢谢,伙计们!

    6 回复  |  直到 8 年前
        1
  •  6
  •   Fredou    15 年前

    我会用 stopwatch 但需要一个循环

    阅读 this 为秒表添加更多扩展,如elapsedmicroseconds

    或者像这样的事情也可能奏效

    系统.诊断.秒表.ishighresolution 必须 是真的

        static void Main(string[] args)
        {
            Stopwatch sw;
            sw = Stopwatch.StartNew();
            int i = 0;
    
            while (sw.ElapsedMilliseconds <= 5000)
            {
                if (sw.Elapsed.Ticks % 100 == 0)
                { i++; /* do something*/ }
            }
            sw.Stop();
    
    
        }
    
        2
  •  9
  •   LBushkin    15 年前

    非常短的睡眠时间通常最好由CPU自旋循环实现(如您所描述的那样)。您通常希望避免使用高精度计时器调用,因为它们本身会占用时间并扭曲结果。我不会太担心在这么短的等待时间内CPU会挂在服务器上。

    我将在一个类中封装行为,如下所示:

    • 创建一个类,该类的静态构造函数将运行一个旋转循环,循环数百万次,并捕获所需的时间。这可以让您了解一个循环周期在底层硬件上需要多长时间。
    • 计算可以用于计算任意睡眠时间的us/迭代值。
    • 当被要求睡眠一段特定时间时,用之前计算的us/迭代值除以us to sleep,以确定要执行的循环迭代次数。
    • 使用while循环旋转,直到估计的时间过去。
        3
  •  1
  •   Eran Betzalel    11 年前

    当我的多播应用程序需要更精确的时候,我已经经历过这种需求。

    我发现最好的解决方案存在于多媒体计时器中,如中所示 this example .

    我使用了这个实现并向它添加了TPL异步调用。你应该看看我的 SimpleMulticastAnalyzer 有关详细信息,请参阅项目。

        4
  •  0
  •   Brian Gideon    15 年前

    你看过吗 multimedia timers ?您可能会在某个地方找到一个.NET库,它将API调用包装在某个地方。

        5
  •  0
  •   jun estevez    11 年前

    我不鼓励使用自旋循环,因为它会消耗并创建阻塞线程。thread.sleep更好,它在睡眠期间不使用处理器资源,它只对时间进行切片。试试看,你将从任务管理器中看到CPU使用率如何随着自旋循环而急剧上升。

        6
  •  0
  •   Ildar    8 年前
        static void udelay(long us)
        {
            var sw = System.Diagnostics.Stopwatch.StartNew();
            long v = (us * System.Diagnostics.Stopwatch.Frequency )/ 1000000;
            while (sw.ElapsedTicks < v)
            {
            }
        }
        static void Main(string[] args)
        {
            for (int i = 0; i < 100; i++)
            {
                Console.WriteLine("" + i + " " + DateTime.Now.Second + "." + DateTime.Now.Millisecond);
                udelay(1000000);
            }
        }