[英]How expensive is the WaitHandle synchronization?
I have heard that WaitHandle
derived synchronization primitives are expensive, but couldn't find further details. 我听说, WaitHandle
派生的同步原语很昂贵,但是找不到更多详细信息。 Is there any performance comparison to other equivalent or similar primitives available? 是否有与其他等效或相似原语的性能比较?
For one particular case, where AutoResetEvent
and Monitor
can be interchanged, the performance of the monitor is at least 1.5 times better (2 times typically). 在一种特殊情况下,可以互换AutoResetEvent
和Monitor
,则Monitor
的性能至少要好1.5倍(通常是2倍)。 This statement is based on the following raw producer/consumer test (Release build) and is valid in the case there is no error in the test logic :o) Anyway, might be usefull for someone... 该语句基于以下原始生产者/消费者测试(发布版本),并且在测试逻辑没有错误的情况下有效:o)无论如何,对于某人可能有用...
Now, I'm trying to be the one who races the horses ;) 现在,我正在努力成为参加比赛的人 ;)
Code: 码:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using Timer = System.Timers.Timer;
namespace ThreadSync2
{
static class Measurement
{
private static readonly Random rng = new Random();
private static long Evaluate(string methodName, Action signal, Action wait)
{
var isProducing = false;
var isConsuming = false;
var mtxData = new object();
var data = new Queue<Tuple<long,int>>();
var produced = 0L;
var consumed = 0L;
var watch = new Stopwatch();
var producer = new Thread(() =>
{
Debug.WriteLine("Production : started.");
while (isProducing)
{
var item = rng.Next(0, 100);
lock (mtxData)
data.Enqueue(new Tuple<long, int>(produced, item));
signal();
Debug.WriteLine($"{watch.Elapsed.Seconds,3:d}.{watch.Elapsed.Milliseconds:d3} Producer: {produced,6:d} [{item,3:d}]");
++produced;
}
Debug.WriteLine("Production : finished.");
}){Name = "Producer"};
var consumer = new Thread(() =>
{
Debug.WriteLine("Consumption: started.");
while ( (isConsuming)
|| (data.Count > 0))
{
while (data.Count > 0)
{
Tuple<long, int> record;
lock (mtxData)
record = data.Dequeue();
Debug.WriteLine($"{watch.Elapsed.Seconds,3:d}.{watch.Elapsed.Milliseconds:d3} Consumer: {record.Item1,6:d} [{record.Item2,3:d}]");
++consumed;
}
wait();
}
Debug.WriteLine("Consumption: finished.");
}){Name = "Consumer"};
var timer = new Timer(5000){AutoReset = false};
timer.Elapsed += (s, e) => {isProducing = false;};
Console.WriteLine($"Evaluating \"{methodName}\"...");
watch.Start();
timer.Enabled = true;
isConsuming = true;
isProducing = true;
consumer.Start();
producer.Start();
producer.Join();
isConsuming = false;
consumer.Join();
watch.Stop();
Console.WriteLine($"Produced items: {produced:### ### ##0}{((produced != consumed) ? $", Consumed items: {consumed:### ### ##0}" : "")}");
Console.WriteLine();
return produced;
}
public static void Evaluate()
{
const string strMonitorLock = "Monitor locking";
const string strWaitHandle = "AutoResetEvent";
const int waitTimeout = 500;
var semMonitorLock = new object();
var semWaitHandle = new AutoResetEvent(false);
var cntMonitorLock = Evaluate
(
strMonitorLock,
() => {lock (semMonitorLock) Monitor.Pulse(semMonitorLock);},
() => {lock (semMonitorLock) Monitor.Wait (semMonitorLock, waitTimeout);}
);
var cntWaitHandle = Evaluate
(
strWaitHandle,
() => semWaitHandle.Set(),
() => semWaitHandle.WaitOne(waitTimeout)
);
Console.WriteLine($"{strMonitorLock} / {strWaitHandle} = {((double)cntMonitorLock / cntWaitHandle):0.000}");
Console.WriteLine();
}
}
class Program
{
static Program()
{
Debug.Listeners.Add(new TextWriterTraceListener(Console.Out));
}
static void Main(string[] args)
{
Measurement.Evaluate();
}
}
}
Console output for repeated executions: 重复执行的控制台输出:
Evaluating "Monitor locking"... Produced items: 15 710 306 Evaluating "AutoResetEvent"... Produced items: 5 998 742 Monitor locking / AutoResetEvent = 2,619 Evaluating "Monitor locking"... Produced items: 11 697 953 Evaluating "AutoResetEvent"... Produced items: 7 119 778 Monitor locking / AutoResetEvent = 1,643 Evaluating "Monitor locking"... Produced items: 11 662 575 Evaluating "AutoResetEvent"... Produced items: 6 437 772 Monitor locking / AutoResetEvent = 1,812 Evaluating "Monitor locking"... Produced items: 12 981 254 Evaluating "AutoResetEvent"... Produced items: 5 934 954 Monitor locking / AutoResetEvent = 2,187 Evaluating "Monitor locking"... Produced items: 14 661 293 Evaluating "AutoResetEvent"... Produced items: 6 370 518 Monitor locking / AutoResetEvent = 2,301 Evaluating "Monitor locking"... Produced items: 15 050 786 Evaluating "AutoResetEvent"... Produced items: 5 912 671 Monitor locking / AutoResetEvent = 2,546
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.