concurrentqueue 怎么用

2025-02-26 20:41:02
推荐回答(1个)
回答1:

相比较于标准锁来说,增加一点工作量即可提高 SpinLock 的性能。但需注意的一点是,SpinLock 比标准锁更耗费资源。您可以使用分析工具中并发分析功能,查看哪种类型的锁可以在您的程序中提供更好的性能。有关更多信息,请参见并发可视化工具。C#VBclass SpinLockDemo2 { constint N = 100000; static Queue _queue = new Queue(); staticobject _lock = new Object(); static SpinLock _spinlock = new SpinLock(); class Data { publicstring Name { get; set; } publicdouble Number { get; set; } } staticvoid Main(string[] args) { // First use a standard lock for comparison purposes. UseLock(); _queue.Clear(); UseSpinLock(); Console.WriteLine("Press a key"); Console.ReadKey(); } privatestaticvoid UpdateWithSpinLock(Data d, int i) { bool lockTaken = false; try { _spinlock.Enter(ref lockTaken); _queue.Enqueue( d ); } finally { if (lockTaken) _spinlock.Exit(false); } } privatestaticvoid UseSpinLock() { Stopwatch sw = Stopwatch.StartNew(); Parallel.Invoke( () => { for (int i = 0; i < N; i++) { UpdateWithSpinLock(new Data() { Name = i.ToString(), Number = i }, i); } }, () => { for (int i = 0; i < N; i++) { UpdateWithSpinLock(new Data() { Name = i.ToString(), Number = i }, i); } } ); sw.Stop(); Console.WriteLine("elapsed ms with spinlock: {0}", sw.ElapsedMilliseconds); } staticvoid UpdateWithLock(Data d, int i) { lock (_lock) { _queue.Enqueue(d); } } privatestaticvoid UseLock() { Stopwatch sw = Stopwatch.StartNew(); Parallel.Invoke( () => { for (int i = 0; i < N; i++) { UpdateWithLock(new Data() { Name = i.ToString(), Number = i }, i); } }, () => { for (int i = 0; i < N; i++) { UpdateWithLock(new Data() { Name = i.ToString(), Number = i }, i); } } ); sw.Stop(); Console.WriteLine("elapsed ms with lock: {0}", sw.ElapsedMilliseconds); } } SpinLock 对于很长时间都不会持有共享资源上的锁的情况可能很有用。对于此类情况,在多核计算机上,一种有效的做法是让已阻塞的线程旋转几个周期,直至锁被释放。通过旋转,线程将不会进入阻塞状态(这是一个占用大量 CPU 资源的过程)。在某些情况下,SpinLock 将会停止旋转,以防止出现逻辑处理器资源不足的现象,或出现系统上超线程的优先级反转的情况。此示例使用 System.Collections.Generic.Queue 类,这要求针对多线程的访问进行用户同步。在以.NET Framework 4 为目标的应用程序中,还可以选择使用 System.Collections.Concurrent.ConcurrentQueue,这不需要任何用户锁。请注意,在对 Exit 的调用中使用了 false(在 Visual Basic 中为 False)。这样可以提供最佳性能。