SPSC 无锁队列2-slot与 uint32_t 共享变量对比实验目标生产者线程将 [0 ~ N) 有序数据发送给消费者线程对比两种实现❌ uint32_t 共享变量错误模型✔ SPSC 无锁队列正确模型验证是否满足有序、不丢失、可消费核心原则不能在两个线程同时修改同个变量SpscQueue2SpscQueue2.h#pragmaonce#includestdint.h/** * brief 无锁环形队列 */class SpscQueue2{private:uint32_tm_buf[2];volatileuint8_tw;volatileuint8_tr;public:SpscQueue2();boolWrite(uint32_tv);boolRead(uint32_tv);};SpscQueue2.cpp#includeSpscQueue2.h#ifdefined(__ARM_ARCH)||defined(__aarch64__)||defined(__arm__)#defineDMB()__asmvolatile(dmb ish:::memory)#else#defineDMB()do{}while(0)#endif/** * brief 初始化 */SpscQueue2::SpscQueue2(){m_buf[0]0;m_buf[1]0;w0;r0;}/** * brief 写入生产者线程 */bool SpscQueue2::Write(uint32_tv){uint8_tnext(w1)1;if(nextr)returnfalse;// fullm_buf[w]v;// 发布顺序DMB();wnext;returntrue;}/** * brief 读取消费者线程 */bool SpscQueue2::Read(uint32_tv){if(rw)returnfalse;// emptyvm_buf[r];// 消费顺序DMB();r(r1)1;returntrue;}测试main.cpp 反例#includeiostream#includethread#includeatomicvolatileuint32_tg_data0;std::atomicboolstart_flag{false};std::atomicboolstop_flag{false};staticconstuint32_tMAX100000;voidwriter(){while(!start_flag.load());for(uint32_ti0;iMAX;i){g_datai;}stop_flag.store(true);}voidreader(){while(!start_flag.load(std::memory_order_acquire));uint32_texpect0;uint32_terror0;uint32_tv;while(expectMAX){vg_data;if(v!expect){std::coutERROR: expect expect got vstd::endl;error;expectv;}expect;}std::coutunsafe done, error errorstd::endl;}intmain(){std::coutstart...std::endl;std::threadt1(writer);std::threadt2(reader);start_flag.store(true);t1.join();t2.join();std::coutfinishstd::endl;}C:\Users\PC\CLionProjects\untitled23\main1.exestart…ERROR: expect 1 got 0ERROR: expect 1 got 99999unsafe done, error 2finishmain.cpp 正例#includeiostream#includethread#includeatomic#includeSpscQueue2.hSpscQueue2 q;std::atomicboolstart_flag{false};std::atomicboolstop_flag{false};staticconstuint32_tMAX100000;voidwriter(){while(!start_flag.load(std::memory_order_acquire));for(uint32_ti0;iMAX;){if(q.Write(i))i;}stop_flag.store(true,std::memory_order_release);}voidreader(){while(!start_flag.load(std::memory_order_acquire));uint32_texpect0;uint32_tv;uint32_terror0;while(expectMAX){bool gotfalse;while(q.Read(v)){gottrue;if(v!expect){std::coutERROR: expect expect got vstd::endl;error;expectv;}expect;}// writer结束 queue空 → 退出if(stop_flag.load(std::memory_order_acquire)!got)break;}std::coutreader done, error errorstd::endl;}intmain(){std::coutstart...std::endl;std::threadt1(writer);std::threadt2(reader);start_flag.store(true,std::memory_order_release);t1.join();t2.join();std::coutfinishstd::endl;}C:\Users\PC\CLionProjects\untitled23\cmake-build-debug\untitled23.exestart…reader done, error 0finish