C++ · 完整文件
06_sync_writer.cpp
在生产者线程执行接收回调;write 返回前完成消息处理。
examples/two_buf_queue/06_sync_writer.cpp
1// Synchronous callbacks run in the producer thread without a reader thread, which is useful for debugging.2// The rest matches asynchronous usage; specify the callback context when constructing the writer: make_writer<Writer<1, true, std::uint16_t, Context>>().3// With multiple writers/producer threads, the callback is automatically protected by a lock.456using namespace TwoBufQueue;78int main() try {9 struct CustomData { int Data; };1011 //---------------1. Initialization--------------------------------------12 std::size_t count = 0;13 const auto writer_thread = std::this_thread::get_id();14 bool same_thread = true;1516 // Consumer callback.17 auto rcvCallback = [&](std::int32_t thread_id, const std::byte* data, std::size_t size) noexcept -> void {18 same_thread &= thread_id == 0 && std::this_thread::get_id() == writer_thread;19 if (++count <= 3) {20 std::printf("message: len = %.*s\n", static_cast<int>(size), reinterpret_cast<const char*>(data));21 } else {// No fixed payload type: decode according to the application's format.22 int type = 0;23 std::memcpy(&type, data, sizeof(type));24 std::printf("message: len = %d, type = %d\n", static_cast<int>(size), type);25 }26 };2728 // A non-void Context selects synchronous handling. The callback type remains inlineable; TwoBufQueue selects locking from the Writer count.29 using Context = SyncContext<decltype(rcvCallback)>;30 auto writer = make_writer<Writer<1, true, std::uint16_t, Context>>(); // Only the Context template argument differs here.31 ::TwoBufQueue::TwoBufQueue queue(rcvCallback, writer); // Bind the callback during construction; do not start a reader thread.3233 //---------------2. Producer writes-------------------------------------34 bool written = true;35 for (std::string_view text : {"hello", "TwoBufQueue", "goodbye"})36 written &= writer.write_mem(text.data(), static_cast<std::uint16_t>(text.size()));3738 // No fixed payload type: the consumer callback decodes the received data using the application's format.39 written &= writer.write(1, 1, static_cast<short>(2));40 written &= writer.write(2, CustomData{3});4142 //---------------3. Finish----------------------------------------------43 writer.finish(); // The application finishes the producer using the existing implementation.44 queue.stop(); // write has already handled each message; this returns the empty source block.4546 //---------------4. Check the result------------------------------------47 example::require(written && count == 5 && same_thread, "write/drain or message count mismatch");48 std::puts("PASS: 5 messages, callback on writer thread");49} catch (const std::exception& error) { std::fprintf(stderr, "%s\n", error.what()); return 1; }