✅ C 无锁环形缓冲区Lock-Free SPSC Ring Buffer以下是现代 C17/20版本的无锁环形缓冲区Single Producer Single Consumer与前面 C# 版本功能对齐性能更高。C17 实现推荐#includeatomic#includecstdint#includevector#includespan#includethread#includechrono#includeiostream#includecstring// memcpytemplatetypenameTclassLockFreeRingBuffer{private:std::vectorT_buffer;constsize_t _capacity;constsize_t _mask;alignas(64)std::atomicsize_t_writeIndex{0};// 生产者alignas(64)std::atomicsize_t_readIndex{0};// 消费者public:explicitLockFreeRingBuffer(size_t capacity65536):_capacity(capacity),_mask(capacity-1),_buffer(capacity){if((capacity(capacity-1))!0){throwstd::invalid_argument(容量必须是 2 的幂);}}// 写入一段数据返回是否成功boolTryProduce(std::spanconstTdata){size_t w_writeIndex.load(std::memory_order_relaxed);size_t r_readIndex.load(std::memory_order_acquire);size_t available_capacity-(w-r);if(availabledata.size()){returnfalse;// 缓冲区满}// 写入数据支持连续内存for(size_t i0;idata.size();i){_buffer[(wi)_mask]data[i];}_writeIndex.store(wdata.size(),std::memory_order_release);returntrue;}// 读取数据返回实际读取数量size_tTryConsume(std::spanTdestination){size_t r_readIndex.load(std::memory_order_relaxed);size_t w_writeIndex.load(std::memory_order_acquire);size_t availablew-r;if(available0)return0;size_t toReadstd::min(available,destination.size());for(size_t i0;itoRead;i){destination[i]_buffer[(ri)_mask];}_readIndex.store(rtoRead,std::memory_order_release);returntoRead;}size_tCount()const{return_writeIndex.load(std::memory_order_acquire)-_readIndex.load(std::memory_order_relaxed);}size_tCapacity()const{return_capacity;}};使用示例功率循环 / ATE 数据采集#includespanvoidPowerCycleDemo(){LockFreeRingBufferuint8_tring(116);// 64KBstd::atomicboolrunning{true};// 生产者线程模拟仪器采集autoproducerstd::thread([](){std::vectoruint8_ttemp(1024);while(running){// 模拟产生测试数据for(size_t i0;itemp.size();i4){floatvstatic_castfloat(i%100)/10.0f;std::memcpy(temp[i],v,sizeof(float));}if(!ring.TryProduce(temp)){std::cout[Producer] 缓冲区满!\n;}std::this_thread::sleep_for(std::chrono::microseconds(500));// 模拟频率}});// 消费者线程autoconsumerstd::thread([](){std::vectoruint8_ttemp(2048);while(running){autoreadring.TryConsume(temp);if(read0){ProcessData(std::spanuint8_t(temp.data(),read));}else{std::this_thread::yield();// 或 SpinWait}}});std::coutC 无锁环形缓冲区功率循环运行中...\n;std::this_thread::sleep_for(std::chrono::seconds(10));runningfalse;producer.join();consumer.join();}voidProcessData(std::spanconstuint8_tdata){if(data.size()4){floatvalue;std::memcpy(value,data.data(),sizeof(float));// std::cout 处理数据: value \n;}}性能优化版C20 std::span更优雅如果你使用C20可以进一步简化boolTryProduce(std::spanconstTdata);// 已经支持进阶技巧使用std::atomic_thread_fence精细控制内存序性能更高。缓存行对齐alignas(64)已使用。支持零拷贝改成存储std::unique_ptr或内存池块。C vs C# 对比总结特性C 版本C# 版本内存管理手动控制更灵活MemoryPool Span无锁实现std::atomic memory orderInterlockedVolatile性能更高无 GC接近但有 GC 影响安全性需小心内存/生命周期更安全需要我加上多生产者版本、使用 Memory Pool Span的零拷贝版本还是集成仪器 API的完整示例随时告诉我