gistfile1.txt
· 20 KiB · Text
原始文件
# 💬 Chat Export: Create a C++ triple buffer cla...
*Exported on: 7/21/2026, 7:27:33 AM*
---
---
**🧑 User**
*7/21/2026, 7:27:33 AM*
> Create a C++ triple buffer class which safely moves data between two threads using atomics. Template this class on the data type to be buffered between the two threads. This data structure should have the same semantics as a "double buffer" common in graphics, where the swapped buffer always contains the latest data. This should not behave like a queue with 3 slots.
---
**🤖 Assistant**
*7/21/2026, 7:27:33 AM*
> Based on the provided context, here is a C++ triple buffer class template designed for safe data movement between two threads using atomics. This implementation follows the "double buffer" semantics common in graphics, where one buffer is always presented (front), another is being written to (back), and a third acts as an intermediate (middle) buffer for swapping and signaling new data availability.
>
> ```cpp
> #include <atomic>
>
> template<typename T>
> class TripleBuffer {
> public:
> // Consumer side: reads from the buffer
> T& Read() {
> // Check if there's newly committed data in the middle buffer
> bool isDirty = dirty_.load(std::memory_order_relaxed);
> if (isDirty) {
> // Swap the front buffer with the middle buffer
> front_buffer_ = middle_buffer_.exchange(front_buffer_, std::memory_order_acq_rel);
> // Reset the dirty flag
> dirty_.store(false, std::memory_order_relaxed);
> }
> return *front_buffer_;
> }
>
> // Producer side: gets the current back buffer to write to it
> T& Write() {
> return *back_buffer_;
> }
>
> // Producer side: commits written data and swaps the back buffer with the middle buffer
> void Commit() {
> // Swap buffer pointers and mark the middle buffer dirty
> back_buffer_ = middle_buffer_.exchange(back_buffer_, std::memory_order_acq_rel);
> dirty_.store(true, std::memory_order_relaxed);
> }
>
> private:
> // Prevent implicit data sharing between threads
> static constexpr size_t kNoSharing = 64;
> struct alignas(kNoSharing) Buffer {
> T data{};
> };
> Buffer buffers_[3];
>
> // Pointers to the three buffers
> alignas(kNoSharing) T* front_buffer_{&buffers_[0].data}; // Only consumer accesses this
> alignas(kNoSharing) T* back_buffer_{&buffers_[2].data}; // Only producer accesses this
> alignas(kNoSharing) T* middle_buffer_{&buffers_[1].data}; // Used for swapping
>
> // Dirty flag: indicates that there's new data in the middle buffer
> std::atomic<bool> dirty_{false};
> };
>
> // Example usage:
> // TripleBuffer<int> triple_buffer;
> //
> // // Producer thread
> // while (true) {
> // int& buffer = triple_buffer.Write();
> // buffer = 42; // Write your data
> // triple_buffer.Commit(); // Signal that data is ready
> // }
> //
> // // Consumer thread
> // while (true) {
> // int& buffer = triple_buffer.Read();
> // // Use the data
> // std::cout << buffer << std::endl;
> // }
> ```
>
> This implementation ensures that the consumer always sees the latest data available, similar to double buffering in graphics. The `Read()` method checks the `dirty_` flag to determine if a swap is needed, and the `Commit()` method signals that new data is available by updating the `middle_buffer_` pointer and setting the `dirty_` flag. The `Write()` method simply returns a reference to the current `back_buffer_` for the producer to write to.
>
> The class uses atomic operations to ensure thread safety, specifically `std::memory_order_relaxed`, `std::memory_order_acquire`, and `std::memory_order_acq_rel` for different operations. The `alignas(kNoSharing)` directive is used to prevent false sharing between the buffers, which can improve performance on multi-core systems.
>
> Please note that this implementation assumes that the data type `T` is small enough to fit within a single cache line, which is typically true for most primitive types and small structs. If you are working with larger data types, you may need to adjust the implementation accordingly.
**Citations:**
- [1] [https://brilliantsugar.github.io/posts/how-i-learned-to-stop-worrying-and-love-juggling-c++-atomics/](https://brilliantsugar.github.io/posts/how-i-learned-to-stop-worrying-and-love-juggling-c++-atomics/)
- [2] [https://en.wikipedia.org/wiki/Multiple_buffering](https://en.wikipedia.org/wiki/Multiple_buffering)
- [3] [https://users.rust-lang.org/t/code-review-triplebuffer-for-sending-huge-objects-between-threads/13787](https://users.rust-lang.org/t/code-review-triplebuffer-for-sending-huge-objects-between-threads/13787)
- [4] [https://medium.com/@sgn00/triple-buffer-lock-free-concurrency-primitive-611848627a1e](https://medium.com/@sgn00/triple-buffer-lock-free-concurrency-primitive-611848627a1e)
- [5] [https://cplusplus.com/forum/general/225158/](https://cplusplus.com/forum/general/225158/)
- [6] [https://stackoverflow.com/questions/2008948/double-buffering-for-game-objects-whats-a-nice-clean-generic-c-way](https://stackoverflow.com/questions/2008948/double-buffering-for-game-objects-whats-a-nice-clean-generic-c-way)
- [7] [https://brilliantsugar.github.io/posts/how-i-learned-to-stop-worrying-and-love-juggling-c++-atomics](https://brilliantsugar.github.io/posts/how-i-learned-to-stop-worrying-and-love-juggling-c++-atomics)
- [8] [https://codereview.stackexchange.com/questions/163810/lock-free-zero-copy-triple-buffer](https://codereview.stackexchange.com/questions/163810/lock-free-zero-copy-triple-buffer)
- [9] [https://www.4rknova.com/blog/2025/09/12/triple-buffering](https://www.4rknova.com/blog/2025/09/12/triple-buffering)
- [10] [https://stackoverflow.com/questions/49352853/how-to-correctly-implement-triple-buffering](https://stackoverflow.com/questions/49352853/how-to-correctly-implement-triple-buffering)
- [11] [https://grokipedia.com/page/Multiple_buffering](https://grokipedia.com/page/Multiple_buffering)
- [12] [https://users.rust-lang.org/t/atomics-triple-buffer/51048](https://users.rust-lang.org/t/atomics-triple-buffer/51048)
- [13] [https://www.studyplan.dev/sdl2/double-buffering](https://www.studyplan.dev/sdl2/double-buffering)
- [14] [https://medium.com/embedworld/move-semantics-in-modern-c-faster-object-transfers-without-copying-d5f1205da44c](https://medium.com/embedworld/move-semantics-in-modern-c-faster-object-transfers-without-copying-d5f1205da44c)
- [15] [https://softwareengineering.stackexchange.com/questions/303666/merits-of-copy-on-write-semantics](https://softwareengineering.stackexchange.com/questions/303666/merits-of-copy-on-write-semantics)
- [16] [https://www.embeddedrelated.com/showarticle/1360.php](https://www.embeddedrelated.com/showarticle/1360.php)
- [17] [https://www.oreilly.com/library/view/the-modern-c/9781788993869/86cfe222-e8e8-409d-b30a-3712aaf6db11.xhtml](https://www.oreilly.com/library/view/the-modern-c/9781788993869/86cfe222-e8e8-409d-b30a-3712aaf6db11.xhtml)
- [18] [https://www.heuristic42.com/blog/67/why-stdmove-and-move-semantics/](https://www.heuristic42.com/blog/67/why-stdmove-and-move-semantics/)
- [19] [https://isocpp.org/blog/2024/02/how-i-learned-to-stop-worrying-and-love-juggling-cpp-atomics-brilliantsugar](https://isocpp.org/blog/2024/02/how-i-learned-to-stop-worrying-and-love-juggling-cpp-atomics-brilliantsugar)
- [20] [https://stackoverflow.com/questions/47563995/double-buffering-vs-triple-buffering-for-vertex-buffers](https://stackoverflow.com/questions/47563995/double-buffering-vs-triple-buffering-for-vertex-buffers)
- [21] [https://gameprogrammingpatterns.com/double-buffer.html](https://gameprogrammingpatterns.com/double-buffer.html)
- [22] [https://stackoverflow.com/questions/60351527/multithreaded-double-buffer](https://stackoverflow.com/questions/60351527/multithreaded-double-buffer)
- [23] [https://www.cs.cornell.edu/courses/cs4620/2017sp/cs4621/lecture08/exhibit01.html](https://www.cs.cornell.edu/courses/cs4620/2017sp/cs4621/lecture08/exhibit01.html)
- [24] [https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/Core/TTripleBuffer](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/Core/TTripleBuffer)
- [25] [https://www.reddit.com/r/gamedev/comments/dfisv7/need_explaination_regarding_multithreading_and/](https://www.reddit.com/r/gamedev/comments/dfisv7/need_explaination_regarding_multithreading_and/)
- [26] [https://learn.microsoft.com/en-us/windows-hardware/drivers/display/triple-buffering](https://learn.microsoft.com/en-us/windows-hardware/drivers/display/triple-buffering)
- [27] [https://www.semanticscholar.org/paper/Simulation-of-Triple-Buffer-Scheme-(Comparison-with-Khan-Bailey/f54f9406392a755fb651a66f408d3364f0f2ba62](https://www.semanticscholar.org/paper/Simulation-of-Triple-Buffer-Scheme-(Comparison-with-Khan-Bailey/f54f9406392a755fb651a66f408d3364f0f2ba62)
- [28] [https://github.com/double-free/double-buffer](https://github.com/double-free/double-buffer)
- [29] [https://github.com/RealTaseny/triple_buffer/tree/master](https://github.com/RealTaseny/triple_buffer/tree/master)
- [30] [https://www.studyplan.dev/sdl2/double-buffering/q/implementing-triple-buffering](https://www.studyplan.dev/sdl2/double-buffering/q/implementing-triple-buffering)
- [31] [https://www.youtube.com/watch?v=aJCgtiN5K14](https://www.youtube.com/watch?v=aJCgtiN5K14)
- [32] [https://stackoverflow.com/questions/23666069/single-producer-single-consumer-data-structure-with-double-buffer-in-c](https://stackoverflow.com/questions/23666069/single-producer-single-consumer-data-structure-with-double-buffer-in-c)
- [33] [https://vector-of-bool.github.io/2020/08/29/buffers-1.html](https://vector-of-bool.github.io/2020/08/29/buffers-1.html)
- [34] [https://www.reddit.com/r/cpp/comments/1dc65b0/what_is_the_most_efficient_way_to_build_a_string/](https://www.reddit.com/r/cpp/comments/1dc65b0/what_is_the_most_efficient_way_to_build_a_string/)
- [35] [https://www.quora.com/I-have-two-buffers-and-want-to-write-the-incoming-data-stream-in-one-while-processing-the-other-Do-I-need-semaphores-mutexes-or-will-some-simple-thread-implementation-work](https://www.quora.com/I-have-two-buffers-and-want-to-write-the-incoming-data-stream-in-one-while-processing-the-other-Do-I-need-semaphores-mutexes-or-will-some-simple-thread-implementation-work)
- [36] [https://www.reddit.com/r/cpp_questions/comments/l7w3p0/what_are_the_recommended_parctises_for_a_double/](https://www.reddit.com/r/cpp_questions/comments/l7w3p0/what_are_the_recommended_parctises_for_a_double/)
- [37] [https://meetingcpp.com/mcpp/slides/2021/MeetingCpp_2021_Lock_Free7814.pdf](https://meetingcpp.com/mcpp/slides/2021/MeetingCpp_2021_Lock_Free7814.pdf)
- [38] [https://github.com/topics/double-buffer](https://github.com/topics/double-buffer)
- [39] [https://github.com/pasteur90/buffering](https://github.com/pasteur90/buffering)
- [40] [https://www.intel.com/content/www/us/en/docs/oneapi-fpga-add-on/optimization-guide/2023-1/apply-dbl-buf.html](https://www.intel.com/content/www/us/en/docs/oneapi-fpga-add-on/optimization-guide/2023-1/apply-dbl-buf.html)
- [41] [https://cs61.seas.harvard.edu/site/2018/Synch2/](https://cs61.seas.harvard.edu/site/2018/Synch2/)
- [42] [https://herbsutter.com/2008/08/05/effective-concurrency-lock-free-code-a-false-sense-of-security/](https://herbsutter.com/2008/08/05/effective-concurrency-lock-free-code-a-false-sense-of-security/)
- [43] [https://cppcheatsheet.com/notes/cpp/cpp_move.html](https://cppcheatsheet.com/notes/cpp/cpp_move.html)
- [44] [https://www.slideserve.com/rsosa/event-handling-powerpoint-ppt-presentation](https://www.slideserve.com/rsosa/event-handling-powerpoint-ppt-presentation)
- [45] [https://vocal.com/resources/development/implement-double-buffering-in-shared-memory/](https://vocal.com/resources/development/implement-double-buffering-in-shared-memory/)
- [46] [https://www.doc.ic.ac.uk/~afd/papers/2009/HiPEAC.pdf](https://www.doc.ic.ac.uk/~afd/papers/2009/HiPEAC.pdf)
- [47] [https://www.gamedeveloper.com/programming/a-c-platform-class-for-cross-platform-double-buffered-graphics](https://www.gamedeveloper.com/programming/a-c-platform-class-for-cross-platform-double-buffered-graphics)
- [48] [https://fr.scribd.com/document/625312732/Buffering-in-Operating-System-javatpoint](https://fr.scribd.com/document/625312732/Buffering-in-Operating-System-javatpoint)
- [49] [https://faculty.cc.gatech.edu/~jarulraj/courses/4420-f23/slides/07-buffer-management-1.pdf](https://faculty.cc.gatech.edu/~jarulraj/courses/4420-f23/slides/07-buffer-management-1.pdf)
- [50] [https://github.com/max0x7ba/atomic_queue](https://github.com/max0x7ba/atomic_queue)
- [51] [https://dev.to/pauljlucas/advanced-thread-safety-in-c-3ap5](https://dev.to/pauljlucas/advanced-thread-safety-in-c-3ap5)
- [52] [https://armarx.humanoids.kit.edu/staging/d8/d04/util_2CPPUtility_2TripleBuffer_8h_source.html](https://armarx.humanoids.kit.edu/staging/d8/d04/util_2CPPUtility_2TripleBuffer_8h_source.html)
- [53] [https://www.quora.com/Using-C-code-can-you-implement-a-thread-safe-stack-using-locks-and-another-one-using-atomic](https://www.quora.com/Using-C-code-can-you-implement-a-thread-safe-stack-using-locks-and-another-one-using-atomic)
- [54] [https://www.reddit.com/r/cpp/comments/1ivlv7e/building_a_fast_spsc_queue_atomics_memory/](https://www.reddit.com/r/cpp/comments/1ivlv7e/building_a_fast_spsc_queue_atomics_memory/)
- [55] [https://jaysmito.dev/blog/blog/04-fast-lockfree-queues/](https://jaysmito.dev/blog/blog/04-fast-lockfree-queues/)
- [56] [https://blog.bearcats.nl/simple-message-queue/](https://blog.bearcats.nl/simple-message-queue/)
- [57] [https://stackoverflow.com/questions/38593080/can-a-shared-buffer-be-thread-safe-using-stdatomic-flags-is-there-a-more-effi](https://stackoverflow.com/questions/38593080/can-a-shared-buffer-be-thread-safe-using-stdatomic-flags-is-there-a-more-effi)
- [58] [https://stackoverflow.com/questions/53038437/ring-buffer-with-atomic-indexes](https://stackoverflow.com/questions/53038437/ring-buffer-with-atomic-indexes)
- [59] [https://medium.com/@serhatg2490/spsc-lock-free-queue-implementation-using-c-20-dd7a140d10f9](https://medium.com/@serhatg2490/spsc-lock-free-queue-implementation-using-c-20-dd7a140d10f9)
- [60] [https://pmbanugo.me/blog/building-lock-free-spsc-queue](https://pmbanugo.me/blog/building-lock-free-spsc-queue)
- [61] [https://embeddedartistry.com/blog/2017/05/17/creating-a-circular-buffer-in-c-and-c/](https://embeddedartistry.com/blog/2017/05/17/creating-a-circular-buffer-in-c-and-c/)
- [62] [https://radiantsoftware.hashnode.dev/c-lock-free-object-pool](https://radiantsoftware.hashnode.dev/c-lock-free-object-pool)
- [63] [https://algomaster.io/learn/concurrency-interview/design-thread-safe-blocking-queue](https://algomaster.io/learn/concurrency-interview/design-thread-safe-blocking-queue)
- [64] [https://www.linkedin.com/pulse/lock-free-practice-engineering-high-throughput-spsc-ring-tonetti-deiwe](https://www.linkedin.com/pulse/lock-free-practice-engineering-high-throughput-spsc-ring-tonetti-deiwe)
- [65] [https://www.bellw3ther.tech/blog/ring_buffer](https://www.bellw3ther.tech/blog/ring_buffer)
- [66] [https://max0x7ba.github.io/atomic_queue/](https://max0x7ba.github.io/atomic_queue/)
- [67] [https://r18a.nl/triple-buffering/](https://r18a.nl/triple-buffering/)
- [68] [https://github.com/rezabrizi/AtomicRing](https://github.com/rezabrizi/AtomicRing)
- [69] [https://github.com/hmvyp/ntuplebuf/](https://github.com/hmvyp/ntuplebuf/)
- [70] [https://www.reddit.com/r/cpp/comments/1ivlv7e/building_a_fast_spsc_queue_atomics_memory](https://www.reddit.com/r/cpp/comments/1ivlv7e/building_a_fast_spsc_queue_atomics_memory)
- [71] [https://codereview.stackexchange.com/questions/293537/ring-buffer-implementation-in-c](https://codereview.stackexchange.com/questions/293537/ring-buffer-implementation-in-c)
- [72] [https://martinuke0.github.io/posts/2026-05-15-the-mechanics-of-thread-safety-in-lockless-circular-buffers/](https://martinuke0.github.io/posts/2026-05-15-the-mechanics-of-thread-safety-in-lockless-circular-buffers/)
- [73] [https://gist.github.com/mrizaln/34d7873d13043d68c0ed31d692b921d4](https://gist.github.com/mrizaln/34d7873d13043d68c0ed31d692b921d4)
- [74] [https://landenlabs.com/code/ring/ring.html](https://landenlabs.com/code/ring/ring.html)
- [75] [https://forum.arduino.cc/t/thread-safe-data-transfer-interlock-using-std-atomic-and-std-memory-order/1159080](https://forum.arduino.cc/t/thread-safe-data-transfer-interlock-using-std-atomic-and-std-memory-order/1159080)
- [76] [https://cppreference.net/cpp/atomic.html](https://cppreference.net/cpp/atomic.html)
- [77] [https://dev.to/lakshya_bankey_27825e4908/building-a-high-performance-lock-free-ring-buffer-in-c-for-ultra-low-latency-messaging-19h6](https://dev.to/lakshya_bankey_27825e4908/building-a-high-performance-lock-free-ring-buffer-in-c-for-ultra-low-latency-messaging-19h6)
- [78] [https://www.studyplan.dev/dsa/spsc-lock-free-queue](https://www.studyplan.dev/dsa/spsc-lock-free-queue)
- [79] [https://llvm.org/docs/Atomics.html](https://llvm.org/docs/Atomics.html)
- [80] [https://stackoverflow.com/questions/871234/circular-lock-free-buffer](https://stackoverflow.com/questions/871234/circular-lock-free-buffer)
- [81] [https://news.ycombinator.com/item?id=47501875](https://news.ycombinator.com/item?id=47501875)
- [82] [https://hasaranga.com/ai/atomics.html](https://hasaranga.com/ai/atomics.html)
- [83] [https://buzzdb-docs.readthedocs.io/part1/lab2.html](https://buzzdb-docs.readthedocs.io/part1/lab2.html)
- [84] [https://medium.com/@david-alvarez-rosa/optimizing-a-lock-free-ring-buffer-c59afcc7b479](https://medium.com/@david-alvarez-rosa/optimizing-a-lock-free-ring-buffer-c59afcc7b479)
- [85] [https://www.joewood.me/posts/lock-free-ring-buffer](https://www.joewood.me/posts/lock-free-ring-buffer)
- [86] [https://github.com/p4checo/triplebuffer-sync](https://github.com/p4checo/triplebuffer-sync)
- [87] [https://lavag.org/topic/18587-how-to-implement-triple-buffering/](https://lavag.org/topic/18587-how-to-implement-triple-buffering/)
- [88] [https://stackoverflow.com/questions/15204578/c11-atomic-memory-ordering-is-this-a-correct-usage-of-relaxed-release-consu](https://stackoverflow.com/questions/15204578/c11-atomic-memory-ordering-is-this-a-correct-usage-of-relaxed-release-consu)
- [89] [https://github.com/remis-thoughts/blog/blob/master/triple-buffering/src/main/md/triple-buffering.md](https://github.com/remis-thoughts/blog/blob/master/triple-buffering/src/main/md/triple-buffering.md)
- [90] [https://github.com/HadrienG2/triple-buffer](https://github.com/HadrienG2/triple-buffer)
- [91] [https://community.vcvrack.com/t/worker-threads/19282](https://community.vcvrack.com/t/worker-threads/19282)
- [92] [https://docs.nvidia.com/cuda/cuda-c-programming-guide/](https://docs.nvidia.com/cuda/cuda-c-programming-guide/)
- [93] [https://robotlabx.com/blog/2023-01-08-Multithreading-C++-8-Atomic/](https://robotlabx.com/blog/2023-01-08-Multithreading-C++-8-Atomic/)
- [94] [https://dev.to/cear/multithreading-in-modern-c-lock-free-programming-memory-ordering-and-atomics-4cek](https://dev.to/cear/multithreading-in-modern-c-lock-free-programming-memory-ordering-and-atomics-4cek)
- [95] [https://www.youtube.com/watch?v=bjz_bMNNWRk](https://www.youtube.com/watch?v=bjz_bMNNWRk)
- [96] [https://www.reddit.com/r/cpp_questions/comments/1ld5qwq/passing_data_between_threads_design_improvements/](https://www.reddit.com/r/cpp_questions/comments/1ld5qwq/passing_data_between_threads_design_improvements/)
- [97] [https://github.com/adrian-gierakowski/lockless_tripplebuffer](https://github.com/adrian-gierakowski/lockless_tripplebuffer)
- [98] [https://dev.epicgames.com/documentation/unreal-engine/API/Runtime/Chaos/TTripleBufferedData?lang=en-US](https://dev.epicgames
| 1 | # 💬 Chat Export: Create a C++ triple buffer cla... |
| 2 | |
| 3 | *Exported on: 7/21/2026, 7:27:33 AM* |
| 4 | |
| 5 | --- |
| 6 | |
| 7 | --- |
| 8 | **🧑 User** |
| 9 | *7/21/2026, 7:27:33 AM* |
| 10 | |
| 11 | > Create a C++ triple buffer class which safely moves data between two threads using atomics. Template this class on the data type to be buffered between the two threads. This data structure should have the same semantics as a "double buffer" common in graphics, where the swapped buffer always contains the latest data. This should not behave like a queue with 3 slots. |
| 12 | |
| 13 | --- |
| 14 | **🤖 Assistant** |
| 15 | *7/21/2026, 7:27:33 AM* |
| 16 | |
| 17 | > Based on the provided context, here is a C++ triple buffer class template designed for safe data movement between two threads using atomics. This implementation follows the "double buffer" semantics common in graphics, where one buffer is always presented (front), another is being written to (back), and a third acts as an intermediate (middle) buffer for swapping and signaling new data availability. |
| 18 | > |
| 19 | > ```cpp |
| 20 | > #include <atomic> |
| 21 | > |
| 22 | > template<typename T> |
| 23 | > class TripleBuffer { |
| 24 | > public: |
| 25 | > // Consumer side: reads from the buffer |
| 26 | > T& Read() { |
| 27 | > // Check if there's newly committed data in the middle buffer |
| 28 | > bool isDirty = dirty_.load(std::memory_order_relaxed); |
| 29 | > if (isDirty) { |
| 30 | > // Swap the front buffer with the middle buffer |
| 31 | > front_buffer_ = middle_buffer_.exchange(front_buffer_, std::memory_order_acq_rel); |
| 32 | > // Reset the dirty flag |
| 33 | > dirty_.store(false, std::memory_order_relaxed); |
| 34 | > } |
| 35 | > return *front_buffer_; |
| 36 | > } |
| 37 | > |
| 38 | > // Producer side: gets the current back buffer to write to it |
| 39 | > T& Write() { |
| 40 | > return *back_buffer_; |
| 41 | > } |
| 42 | > |
| 43 | > // Producer side: commits written data and swaps the back buffer with the middle buffer |
| 44 | > void Commit() { |
| 45 | > // Swap buffer pointers and mark the middle buffer dirty |
| 46 | > back_buffer_ = middle_buffer_.exchange(back_buffer_, std::memory_order_acq_rel); |
| 47 | > dirty_.store(true, std::memory_order_relaxed); |
| 48 | > } |
| 49 | > |
| 50 | > private: |
| 51 | > // Prevent implicit data sharing between threads |
| 52 | > static constexpr size_t kNoSharing = 64; |
| 53 | > struct alignas(kNoSharing) Buffer { |
| 54 | > T data{}; |
| 55 | > }; |
| 56 | > Buffer buffers_[3]; |
| 57 | > |
| 58 | > // Pointers to the three buffers |
| 59 | > alignas(kNoSharing) T* front_buffer_{&buffers_[0].data}; // Only consumer accesses this |
| 60 | > alignas(kNoSharing) T* back_buffer_{&buffers_[2].data}; // Only producer accesses this |
| 61 | > alignas(kNoSharing) T* middle_buffer_{&buffers_[1].data}; // Used for swapping |
| 62 | > |
| 63 | > // Dirty flag: indicates that there's new data in the middle buffer |
| 64 | > std::atomic<bool> dirty_{false}; |
| 65 | > }; |
| 66 | > |
| 67 | > // Example usage: |
| 68 | > // TripleBuffer<int> triple_buffer; |
| 69 | > // |
| 70 | > // // Producer thread |
| 71 | > // while (true) { |
| 72 | > // int& buffer = triple_buffer.Write(); |
| 73 | > // buffer = 42; // Write your data |
| 74 | > // triple_buffer.Commit(); // Signal that data is ready |
| 75 | > // } |
| 76 | > // |
| 77 | > // // Consumer thread |
| 78 | > // while (true) { |
| 79 | > // int& buffer = triple_buffer.Read(); |
| 80 | > // // Use the data |
| 81 | > // std::cout << buffer << std::endl; |
| 82 | > // } |
| 83 | > ``` |
| 84 | > |
| 85 | > This implementation ensures that the consumer always sees the latest data available, similar to double buffering in graphics. The `Read()` method checks the `dirty_` flag to determine if a swap is needed, and the `Commit()` method signals that new data is available by updating the `middle_buffer_` pointer and setting the `dirty_` flag. The `Write()` method simply returns a reference to the current `back_buffer_` for the producer to write to. |
| 86 | > |
| 87 | > The class uses atomic operations to ensure thread safety, specifically `std::memory_order_relaxed`, `std::memory_order_acquire`, and `std::memory_order_acq_rel` for different operations. The `alignas(kNoSharing)` directive is used to prevent false sharing between the buffers, which can improve performance on multi-core systems. |
| 88 | > |
| 89 | > Please note that this implementation assumes that the data type `T` is small enough to fit within a single cache line, which is typically true for most primitive types and small structs. If you are working with larger data types, you may need to adjust the implementation accordingly. |
| 90 | |
| 91 | **Citations:** |
| 92 | - [1] [https://brilliantsugar.github.io/posts/how-i-learned-to-stop-worrying-and-love-juggling-c++-atomics/](https://brilliantsugar.github.io/posts/how-i-learned-to-stop-worrying-and-love-juggling-c++-atomics/) |
| 93 | - [2] [https://en.wikipedia.org/wiki/Multiple_buffering](https://en.wikipedia.org/wiki/Multiple_buffering) |
| 94 | - [3] [https://users.rust-lang.org/t/code-review-triplebuffer-for-sending-huge-objects-between-threads/13787](https://users.rust-lang.org/t/code-review-triplebuffer-for-sending-huge-objects-between-threads/13787) |
| 95 | - [4] [https://medium.com/@sgn00/triple-buffer-lock-free-concurrency-primitive-611848627a1e](https://medium.com/@sgn00/triple-buffer-lock-free-concurrency-primitive-611848627a1e) |
| 96 | - [5] [https://cplusplus.com/forum/general/225158/](https://cplusplus.com/forum/general/225158/) |
| 97 | - [6] [https://stackoverflow.com/questions/2008948/double-buffering-for-game-objects-whats-a-nice-clean-generic-c-way](https://stackoverflow.com/questions/2008948/double-buffering-for-game-objects-whats-a-nice-clean-generic-c-way) |
| 98 | - [7] [https://brilliantsugar.github.io/posts/how-i-learned-to-stop-worrying-and-love-juggling-c++-atomics](https://brilliantsugar.github.io/posts/how-i-learned-to-stop-worrying-and-love-juggling-c++-atomics) |
| 99 | - [8] [https://codereview.stackexchange.com/questions/163810/lock-free-zero-copy-triple-buffer](https://codereview.stackexchange.com/questions/163810/lock-free-zero-copy-triple-buffer) |
| 100 | - [9] [https://www.4rknova.com/blog/2025/09/12/triple-buffering](https://www.4rknova.com/blog/2025/09/12/triple-buffering) |
| 101 | - [10] [https://stackoverflow.com/questions/49352853/how-to-correctly-implement-triple-buffering](https://stackoverflow.com/questions/49352853/how-to-correctly-implement-triple-buffering) |
| 102 | - [11] [https://grokipedia.com/page/Multiple_buffering](https://grokipedia.com/page/Multiple_buffering) |
| 103 | - [12] [https://users.rust-lang.org/t/atomics-triple-buffer/51048](https://users.rust-lang.org/t/atomics-triple-buffer/51048) |
| 104 | - [13] [https://www.studyplan.dev/sdl2/double-buffering](https://www.studyplan.dev/sdl2/double-buffering) |
| 105 | - [14] [https://medium.com/embedworld/move-semantics-in-modern-c-faster-object-transfers-without-copying-d5f1205da44c](https://medium.com/embedworld/move-semantics-in-modern-c-faster-object-transfers-without-copying-d5f1205da44c) |
| 106 | - [15] [https://softwareengineering.stackexchange.com/questions/303666/merits-of-copy-on-write-semantics](https://softwareengineering.stackexchange.com/questions/303666/merits-of-copy-on-write-semantics) |
| 107 | - [16] [https://www.embeddedrelated.com/showarticle/1360.php](https://www.embeddedrelated.com/showarticle/1360.php) |
| 108 | - [17] [https://www.oreilly.com/library/view/the-modern-c/9781788993869/86cfe222-e8e8-409d-b30a-3712aaf6db11.xhtml](https://www.oreilly.com/library/view/the-modern-c/9781788993869/86cfe222-e8e8-409d-b30a-3712aaf6db11.xhtml) |
| 109 | - [18] [https://www.heuristic42.com/blog/67/why-stdmove-and-move-semantics/](https://www.heuristic42.com/blog/67/why-stdmove-and-move-semantics/) |
| 110 | - [19] [https://isocpp.org/blog/2024/02/how-i-learned-to-stop-worrying-and-love-juggling-cpp-atomics-brilliantsugar](https://isocpp.org/blog/2024/02/how-i-learned-to-stop-worrying-and-love-juggling-cpp-atomics-brilliantsugar) |
| 111 | - [20] [https://stackoverflow.com/questions/47563995/double-buffering-vs-triple-buffering-for-vertex-buffers](https://stackoverflow.com/questions/47563995/double-buffering-vs-triple-buffering-for-vertex-buffers) |
| 112 | - [21] [https://gameprogrammingpatterns.com/double-buffer.html](https://gameprogrammingpatterns.com/double-buffer.html) |
| 113 | - [22] [https://stackoverflow.com/questions/60351527/multithreaded-double-buffer](https://stackoverflow.com/questions/60351527/multithreaded-double-buffer) |
| 114 | - [23] [https://www.cs.cornell.edu/courses/cs4620/2017sp/cs4621/lecture08/exhibit01.html](https://www.cs.cornell.edu/courses/cs4620/2017sp/cs4621/lecture08/exhibit01.html) |
| 115 | - [24] [https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/Core/TTripleBuffer](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/Core/TTripleBuffer) |
| 116 | - [25] [https://www.reddit.com/r/gamedev/comments/dfisv7/need_explaination_regarding_multithreading_and/](https://www.reddit.com/r/gamedev/comments/dfisv7/need_explaination_regarding_multithreading_and/) |
| 117 | - [26] [https://learn.microsoft.com/en-us/windows-hardware/drivers/display/triple-buffering](https://learn.microsoft.com/en-us/windows-hardware/drivers/display/triple-buffering) |
| 118 | - [27] [https://www.semanticscholar.org/paper/Simulation-of-Triple-Buffer-Scheme-(Comparison-with-Khan-Bailey/f54f9406392a755fb651a66f408d3364f0f2ba62](https://www.semanticscholar.org/paper/Simulation-of-Triple-Buffer-Scheme-(Comparison-with-Khan-Bailey/f54f9406392a755fb651a66f408d3364f0f2ba62) |
| 119 | - [28] [https://github.com/double-free/double-buffer](https://github.com/double-free/double-buffer) |
| 120 | - [29] [https://github.com/RealTaseny/triple_buffer/tree/master](https://github.com/RealTaseny/triple_buffer/tree/master) |
| 121 | - [30] [https://www.studyplan.dev/sdl2/double-buffering/q/implementing-triple-buffering](https://www.studyplan.dev/sdl2/double-buffering/q/implementing-triple-buffering) |
| 122 | - [31] [https://www.youtube.com/watch?v=aJCgtiN5K14](https://www.youtube.com/watch?v=aJCgtiN5K14) |
| 123 | - [32] [https://stackoverflow.com/questions/23666069/single-producer-single-consumer-data-structure-with-double-buffer-in-c](https://stackoverflow.com/questions/23666069/single-producer-single-consumer-data-structure-with-double-buffer-in-c) |
| 124 | - [33] [https://vector-of-bool.github.io/2020/08/29/buffers-1.html](https://vector-of-bool.github.io/2020/08/29/buffers-1.html) |
| 125 | - [34] [https://www.reddit.com/r/cpp/comments/1dc65b0/what_is_the_most_efficient_way_to_build_a_string/](https://www.reddit.com/r/cpp/comments/1dc65b0/what_is_the_most_efficient_way_to_build_a_string/) |
| 126 | - [35] [https://www.quora.com/I-have-two-buffers-and-want-to-write-the-incoming-data-stream-in-one-while-processing-the-other-Do-I-need-semaphores-mutexes-or-will-some-simple-thread-implementation-work](https://www.quora.com/I-have-two-buffers-and-want-to-write-the-incoming-data-stream-in-one-while-processing-the-other-Do-I-need-semaphores-mutexes-or-will-some-simple-thread-implementation-work) |
| 127 | - [36] [https://www.reddit.com/r/cpp_questions/comments/l7w3p0/what_are_the_recommended_parctises_for_a_double/](https://www.reddit.com/r/cpp_questions/comments/l7w3p0/what_are_the_recommended_parctises_for_a_double/) |
| 128 | - [37] [https://meetingcpp.com/mcpp/slides/2021/MeetingCpp_2021_Lock_Free7814.pdf](https://meetingcpp.com/mcpp/slides/2021/MeetingCpp_2021_Lock_Free7814.pdf) |
| 129 | - [38] [https://github.com/topics/double-buffer](https://github.com/topics/double-buffer) |
| 130 | - [39] [https://github.com/pasteur90/buffering](https://github.com/pasteur90/buffering) |
| 131 | - [40] [https://www.intel.com/content/www/us/en/docs/oneapi-fpga-add-on/optimization-guide/2023-1/apply-dbl-buf.html](https://www.intel.com/content/www/us/en/docs/oneapi-fpga-add-on/optimization-guide/2023-1/apply-dbl-buf.html) |
| 132 | - [41] [https://cs61.seas.harvard.edu/site/2018/Synch2/](https://cs61.seas.harvard.edu/site/2018/Synch2/) |
| 133 | - [42] [https://herbsutter.com/2008/08/05/effective-concurrency-lock-free-code-a-false-sense-of-security/](https://herbsutter.com/2008/08/05/effective-concurrency-lock-free-code-a-false-sense-of-security/) |
| 134 | - [43] [https://cppcheatsheet.com/notes/cpp/cpp_move.html](https://cppcheatsheet.com/notes/cpp/cpp_move.html) |
| 135 | - [44] [https://www.slideserve.com/rsosa/event-handling-powerpoint-ppt-presentation](https://www.slideserve.com/rsosa/event-handling-powerpoint-ppt-presentation) |
| 136 | - [45] [https://vocal.com/resources/development/implement-double-buffering-in-shared-memory/](https://vocal.com/resources/development/implement-double-buffering-in-shared-memory/) |
| 137 | - [46] [https://www.doc.ic.ac.uk/~afd/papers/2009/HiPEAC.pdf](https://www.doc.ic.ac.uk/~afd/papers/2009/HiPEAC.pdf) |
| 138 | - [47] [https://www.gamedeveloper.com/programming/a-c-platform-class-for-cross-platform-double-buffered-graphics](https://www.gamedeveloper.com/programming/a-c-platform-class-for-cross-platform-double-buffered-graphics) |
| 139 | - [48] [https://fr.scribd.com/document/625312732/Buffering-in-Operating-System-javatpoint](https://fr.scribd.com/document/625312732/Buffering-in-Operating-System-javatpoint) |
| 140 | - [49] [https://faculty.cc.gatech.edu/~jarulraj/courses/4420-f23/slides/07-buffer-management-1.pdf](https://faculty.cc.gatech.edu/~jarulraj/courses/4420-f23/slides/07-buffer-management-1.pdf) |
| 141 | - [50] [https://github.com/max0x7ba/atomic_queue](https://github.com/max0x7ba/atomic_queue) |
| 142 | - [51] [https://dev.to/pauljlucas/advanced-thread-safety-in-c-3ap5](https://dev.to/pauljlucas/advanced-thread-safety-in-c-3ap5) |
| 143 | - [52] [https://armarx.humanoids.kit.edu/staging/d8/d04/util_2CPPUtility_2TripleBuffer_8h_source.html](https://armarx.humanoids.kit.edu/staging/d8/d04/util_2CPPUtility_2TripleBuffer_8h_source.html) |
| 144 | - [53] [https://www.quora.com/Using-C-code-can-you-implement-a-thread-safe-stack-using-locks-and-another-one-using-atomic](https://www.quora.com/Using-C-code-can-you-implement-a-thread-safe-stack-using-locks-and-another-one-using-atomic) |
| 145 | - [54] [https://www.reddit.com/r/cpp/comments/1ivlv7e/building_a_fast_spsc_queue_atomics_memory/](https://www.reddit.com/r/cpp/comments/1ivlv7e/building_a_fast_spsc_queue_atomics_memory/) |
| 146 | - [55] [https://jaysmito.dev/blog/blog/04-fast-lockfree-queues/](https://jaysmito.dev/blog/blog/04-fast-lockfree-queues/) |
| 147 | - [56] [https://blog.bearcats.nl/simple-message-queue/](https://blog.bearcats.nl/simple-message-queue/) |
| 148 | - [57] [https://stackoverflow.com/questions/38593080/can-a-shared-buffer-be-thread-safe-using-stdatomic-flags-is-there-a-more-effi](https://stackoverflow.com/questions/38593080/can-a-shared-buffer-be-thread-safe-using-stdatomic-flags-is-there-a-more-effi) |
| 149 | - [58] [https://stackoverflow.com/questions/53038437/ring-buffer-with-atomic-indexes](https://stackoverflow.com/questions/53038437/ring-buffer-with-atomic-indexes) |
| 150 | - [59] [https://medium.com/@serhatg2490/spsc-lock-free-queue-implementation-using-c-20-dd7a140d10f9](https://medium.com/@serhatg2490/spsc-lock-free-queue-implementation-using-c-20-dd7a140d10f9) |
| 151 | - [60] [https://pmbanugo.me/blog/building-lock-free-spsc-queue](https://pmbanugo.me/blog/building-lock-free-spsc-queue) |
| 152 | - [61] [https://embeddedartistry.com/blog/2017/05/17/creating-a-circular-buffer-in-c-and-c/](https://embeddedartistry.com/blog/2017/05/17/creating-a-circular-buffer-in-c-and-c/) |
| 153 | - [62] [https://radiantsoftware.hashnode.dev/c-lock-free-object-pool](https://radiantsoftware.hashnode.dev/c-lock-free-object-pool) |
| 154 | - [63] [https://algomaster.io/learn/concurrency-interview/design-thread-safe-blocking-queue](https://algomaster.io/learn/concurrency-interview/design-thread-safe-blocking-queue) |
| 155 | - [64] [https://www.linkedin.com/pulse/lock-free-practice-engineering-high-throughput-spsc-ring-tonetti-deiwe](https://www.linkedin.com/pulse/lock-free-practice-engineering-high-throughput-spsc-ring-tonetti-deiwe) |
| 156 | - [65] [https://www.bellw3ther.tech/blog/ring_buffer](https://www.bellw3ther.tech/blog/ring_buffer) |
| 157 | - [66] [https://max0x7ba.github.io/atomic_queue/](https://max0x7ba.github.io/atomic_queue/) |
| 158 | - [67] [https://r18a.nl/triple-buffering/](https://r18a.nl/triple-buffering/) |
| 159 | - [68] [https://github.com/rezabrizi/AtomicRing](https://github.com/rezabrizi/AtomicRing) |
| 160 | - [69] [https://github.com/hmvyp/ntuplebuf/](https://github.com/hmvyp/ntuplebuf/) |
| 161 | - [70] [https://www.reddit.com/r/cpp/comments/1ivlv7e/building_a_fast_spsc_queue_atomics_memory](https://www.reddit.com/r/cpp/comments/1ivlv7e/building_a_fast_spsc_queue_atomics_memory) |
| 162 | - [71] [https://codereview.stackexchange.com/questions/293537/ring-buffer-implementation-in-c](https://codereview.stackexchange.com/questions/293537/ring-buffer-implementation-in-c) |
| 163 | - [72] [https://martinuke0.github.io/posts/2026-05-15-the-mechanics-of-thread-safety-in-lockless-circular-buffers/](https://martinuke0.github.io/posts/2026-05-15-the-mechanics-of-thread-safety-in-lockless-circular-buffers/) |
| 164 | - [73] [https://gist.github.com/mrizaln/34d7873d13043d68c0ed31d692b921d4](https://gist.github.com/mrizaln/34d7873d13043d68c0ed31d692b921d4) |
| 165 | - [74] [https://landenlabs.com/code/ring/ring.html](https://landenlabs.com/code/ring/ring.html) |
| 166 | - [75] [https://forum.arduino.cc/t/thread-safe-data-transfer-interlock-using-std-atomic-and-std-memory-order/1159080](https://forum.arduino.cc/t/thread-safe-data-transfer-interlock-using-std-atomic-and-std-memory-order/1159080) |
| 167 | - [76] [https://cppreference.net/cpp/atomic.html](https://cppreference.net/cpp/atomic.html) |
| 168 | - [77] [https://dev.to/lakshya_bankey_27825e4908/building-a-high-performance-lock-free-ring-buffer-in-c-for-ultra-low-latency-messaging-19h6](https://dev.to/lakshya_bankey_27825e4908/building-a-high-performance-lock-free-ring-buffer-in-c-for-ultra-low-latency-messaging-19h6) |
| 169 | - [78] [https://www.studyplan.dev/dsa/spsc-lock-free-queue](https://www.studyplan.dev/dsa/spsc-lock-free-queue) |
| 170 | - [79] [https://llvm.org/docs/Atomics.html](https://llvm.org/docs/Atomics.html) |
| 171 | - [80] [https://stackoverflow.com/questions/871234/circular-lock-free-buffer](https://stackoverflow.com/questions/871234/circular-lock-free-buffer) |
| 172 | - [81] [https://news.ycombinator.com/item?id=47501875](https://news.ycombinator.com/item?id=47501875) |
| 173 | - [82] [https://hasaranga.com/ai/atomics.html](https://hasaranga.com/ai/atomics.html) |
| 174 | - [83] [https://buzzdb-docs.readthedocs.io/part1/lab2.html](https://buzzdb-docs.readthedocs.io/part1/lab2.html) |
| 175 | - [84] [https://medium.com/@david-alvarez-rosa/optimizing-a-lock-free-ring-buffer-c59afcc7b479](https://medium.com/@david-alvarez-rosa/optimizing-a-lock-free-ring-buffer-c59afcc7b479) |
| 176 | - [85] [https://www.joewood.me/posts/lock-free-ring-buffer](https://www.joewood.me/posts/lock-free-ring-buffer) |
| 177 | - [86] [https://github.com/p4checo/triplebuffer-sync](https://github.com/p4checo/triplebuffer-sync) |
| 178 | - [87] [https://lavag.org/topic/18587-how-to-implement-triple-buffering/](https://lavag.org/topic/18587-how-to-implement-triple-buffering/) |
| 179 | - [88] [https://stackoverflow.com/questions/15204578/c11-atomic-memory-ordering-is-this-a-correct-usage-of-relaxed-release-consu](https://stackoverflow.com/questions/15204578/c11-atomic-memory-ordering-is-this-a-correct-usage-of-relaxed-release-consu) |
| 180 | - [89] [https://github.com/remis-thoughts/blog/blob/master/triple-buffering/src/main/md/triple-buffering.md](https://github.com/remis-thoughts/blog/blob/master/triple-buffering/src/main/md/triple-buffering.md) |
| 181 | - [90] [https://github.com/HadrienG2/triple-buffer](https://github.com/HadrienG2/triple-buffer) |
| 182 | - [91] [https://community.vcvrack.com/t/worker-threads/19282](https://community.vcvrack.com/t/worker-threads/19282) |
| 183 | - [92] [https://docs.nvidia.com/cuda/cuda-c-programming-guide/](https://docs.nvidia.com/cuda/cuda-c-programming-guide/) |
| 184 | - [93] [https://robotlabx.com/blog/2023-01-08-Multithreading-C++-8-Atomic/](https://robotlabx.com/blog/2023-01-08-Multithreading-C++-8-Atomic/) |
| 185 | - [94] [https://dev.to/cear/multithreading-in-modern-c-lock-free-programming-memory-ordering-and-atomics-4cek](https://dev.to/cear/multithreading-in-modern-c-lock-free-programming-memory-ordering-and-atomics-4cek) |
| 186 | - [95] [https://www.youtube.com/watch?v=bjz_bMNNWRk](https://www.youtube.com/watch?v=bjz_bMNNWRk) |
| 187 | - [96] [https://www.reddit.com/r/cpp_questions/comments/1ld5qwq/passing_data_between_threads_design_improvements/](https://www.reddit.com/r/cpp_questions/comments/1ld5qwq/passing_data_between_threads_design_improvements/) |
| 188 | - [97] [https://github.com/adrian-gierakowski/lockless_tripplebuffer](https://github.com/adrian-gierakowski/lockless_tripplebuffer) |
| 189 | - [98] [https://dev.epicgames.com/documentation/unreal-engine/API/Runtime/Chaos/TTripleBufferedData?lang=en-US](https://dev.epicgames |