| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- namespace MvvmScaffoldFrame48.DLL.SystemTools
- {
- public sealed class LockFreeRingBuffer<T>
- {
- private readonly T[] _buffer;
- private readonly int _mask;
- private volatile int _readIndex;
- private volatile int _writeIndex;
- private readonly int _capacity;
- public LockFreeRingBuffer(int capacity)
- {
- // 容量必须是2的幂次方
- if (!IsPowerOfTwo(capacity))
- capacity = RoundUpToPowerOfTwo(capacity);
- _capacity = capacity;
- _mask = _capacity - 1;
- _buffer = new T[_capacity];
- }
- private static bool IsPowerOfTwo(int x)
- {
- return x > 0 && (x & (x - 1)) == 0;
- }
- private static int RoundUpToPowerOfTwo(int x)
- {
- if (x <= 1) return 1;
- x--;
- x |= x >> 1;
- x |= x >> 2;
- x |= x >> 4;
- x |= x >> 8;
- x |= x >> 16;
- return x + 1;
- }
- public bool TryEnqueue(T item)
- {
- int currentWriteIndex, nextWriteIndex, currentReadIndex;
- do
- {
- currentWriteIndex = _writeIndex;
- currentReadIndex = _readIndex;
- nextWriteIndex = (currentWriteIndex + 1) & _mask;
- // 检查是否已满
- if (nextWriteIndex == currentReadIndex)
- return false;
- } while (Interlocked.CompareExchange(ref _writeIndex, nextWriteIndex, currentWriteIndex) != currentWriteIndex);
- // 设置值并更新发布标记
- _buffer[currentWriteIndex & _mask] = item;
- return true;
- }
- public bool TryDequeue(out T result)
- {
- result = default(T);
- int currentReadIndex, nextReadIndex, currentWriteIndex;
- do
- {
- currentReadIndex = _readIndex;
- currentWriteIndex = _writeIndex;
- // 检查是否为空
- if (currentReadIndex == currentWriteIndex)
- return false;
- nextReadIndex = (currentReadIndex + 1) & _mask;
- } while (Interlocked.CompareExchange(ref _readIndex, nextReadIndex, currentReadIndex) != currentReadIndex);
- result = _buffer[currentReadIndex & _mask];
- _buffer[currentReadIndex & _mask] = default(T); // 防止内存泄漏
- return true;
- }
- public int Count
- {
- get
- {
- int read = _readIndex;
- int write = _writeIndex;
- return (write - read) & _mask;
- }
- }
- }
- }
|