{"id":13418007,"url":"https://github.com/cameron314/readerwriterqueue","last_synced_at":"2025-05-14T15:11:11.408Z","repository":{"id":6819437,"uuid":"8067524","full_name":"cameron314/readerwriterqueue","owner":"cameron314","description":"A fast single-producer, single-consumer lock-free queue for C++","archived":false,"fork":false,"pushed_at":"2024-07-09T11:20:31.000Z","size":227,"stargazers_count":3599,"open_issues_count":17,"forks_count":649,"subscribers_count":143,"default_branch":"master","last_synced_at":"2024-07-31T22:40:36.664Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cameron314.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-02-07T06:03:59.000Z","updated_at":"2024-07-31T12:33:18.000Z","dependencies_parsed_at":"2024-10-26T14:06:23.760Z","dependency_job_id":"d5fb65c7-ca8f-4c8f-a61e-a1eb2395802d","html_url":"https://github.com/cameron314/readerwriterqueue","commit_stats":{"total_commits":136,"total_committers":25,"mean_commits":5.44,"dds":0.3308823529411765,"last_synced_commit":"2dee33ae3edd1e454ac34fea0a27017613355eff"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cameron314%2Freaderwriterqueue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cameron314%2Freaderwriterqueue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cameron314%2Freaderwriterqueue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cameron314%2Freaderwriterqueue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cameron314","download_url":"https://codeload.github.com/cameron314/readerwriterqueue/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248197463,"owners_count":21063619,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T22:00:57.025Z","updated_at":"2025-04-10T09:49:58.486Z","avatar_url":"https://github.com/cameron314.png","language":"C++","readme":"\n# A single-producer, single-consumer lock-free queue for C++\n\nThis mini-repository has my very own implementation of a lock-free queue (that I designed from scratch) for C++.\n\nIt only supports a two-thread use case (one consuming, and one producing). The threads can't switch roles, though\nyou could use this queue completely from a single thread if you wish (but that would sort of defeat the purpose!).\n\nNote: If you need a general-purpose multi-producer, multi-consumer lock free queue, I have [one of those too][mpmc].\n\nThis repository also includes a [circular-buffer SPSC queue][circular] which supports blocking on enqueue as well as dequeue.\n\n\n## Features\n\n- [Blazing fast][benchmarks]\n- Compatible with C++11 (supports moving objects instead of making copies)\n- Fully generic (templated container of any type) -- just like `std::queue`, you never need to allocate memory for elements yourself\n  (which saves you the hassle of writing a lock-free memory manager to hold the elements you're queueing)\n- Allocates memory up front, in contiguous blocks\n- Provides a `try_enqueue` method which is guaranteed never to allocate memory (the queue starts with an initial capacity)\n- Also provides an `enqueue` method which can dynamically grow the size of the queue as needed\n- Also provides `try_emplace`/`emplace` convenience methods\n- Has a blocking version with `wait_dequeue`\n- Completely \"wait-free\" (no compare-and-swap loop). Enqueue and dequeue are always O(1) (not counting memory allocation)\n- On x86, the memory barriers compile down to no-ops, meaning enqueue and dequeue are just a simple series of loads and stores (and branches)\n\n\n## Use\n\nSimply drop the readerwriterqueue.h (or readerwritercircularbuffer.h) and atomicops.h files into your source code and include them :-)\nA modern compiler is required (MSVC2010+, GCC 4.7+, ICC 13+, or any C++11 compliant compiler should work).\n\nNote: If you're using GCC, you really do need GCC 4.7 or above -- [4.6 has a bug][gcc46bug] that prevents the atomic fence primitives\nfrom working correctly.\n\nExample:\n\n```cpp\nusing namespace moodycamel;\n\nReaderWriterQueue\u003cint\u003e q(100);       // Reserve space for at least 100 elements up front\n\nq.enqueue(17);                       // Will allocate memory if the queue is full\nbool succeeded = q.try_enqueue(18);  // Will only succeed if the queue has an empty slot (never allocates)\nassert(succeeded);\n\nint number;\nsucceeded = q.try_dequeue(number);  // Returns false if the queue was empty\n\nassert(succeeded \u0026\u0026 number == 17);\n\n// You can also peek at the front item of the queue (consumer only)\nint* front = q.peek();\nassert(*front == 18);\nsucceeded = q.try_dequeue(number);\nassert(succeeded \u0026\u0026 number == 18);\nfront = q.peek(); \nassert(front == nullptr);           // Returns nullptr if the queue was empty\n```\n\nThe blocking version has the exact same API, with the addition of `wait_dequeue` and\n`wait_dequeue_timed` methods:\n\n```cpp\nBlockingReaderWriterQueue\u003cint\u003e q;\n\nstd::thread reader([\u0026]() {\n    int item;\n#if 1\n    for (int i = 0; i != 100; ++i) {\n        // Fully-blocking:\n        q.wait_dequeue(item);\n    }\n#else\n    for (int i = 0; i != 100; ) {\n        // Blocking with timeout\n        if (q.wait_dequeue_timed(item, std::chrono::milliseconds(5)))\n            ++i;\n    }\n#endif\n});\nstd::thread writer([\u0026]() {\n    for (int i = 0; i != 100; ++i) {\n        q.enqueue(i);\n        std::this_thread::sleep_for(std::chrono::milliseconds(10));\n    }\n});\nwriter.join();\nreader.join();\n\nassert(q.size_approx() == 0);\n```\n    \nNote that `wait_dequeue` will block indefinitely while the queue is empty; this\nmeans care must be taken to only call `wait_dequeue` if you're sure another element\nwill come along eventually, or if the queue has a static lifetime. This is because\ndestroying the queue while a thread is waiting on it will invoke undefined behaviour.\n\nThe blocking circular buffer has a fixed number of slots, but is otherwise quite similar to\nuse:\n\n```cpp\nBlockingReaderWriterCircularBuffer\u003cint\u003e q(1024);  // pass initial capacity\n\nq.try_enqueue(1);\nint number;\nq.try_dequeue(number);\nassert(number == 1);\n\nq.wait_enqueue(123);\nq.wait_dequeue(number);\nassert(number == 123);\n\nq.wait_dequeue_timed(number, std::chrono::milliseconds(10));\n```\n\n\n## CMake\n### Using targets in your project\nUsing this project as a part of an existing CMake project is easy.\n\nIn your CMakeLists.txt:\n```\ninclude(FetchContent)\n\nFetchContent_Declare(\n  readerwriterqueue\n  GIT_REPOSITORY    https://github.com/cameron314/readerwriterqueue\n  GIT_TAG           master\n)\n\nFetchContent_MakeAvailable(readerwriterqueue)\n\nadd_library(my_target main.cpp)\ntarget_link_libraries(my_target PUBLIC readerwriterqueue)\n```\n\nIn main.cpp:\n```cpp\n#include \u003creaderwriterqueue.h\u003e\n\nint main()\n{\n    moodycamel::ReaderWriterQueue\u003cint\u003e q(100);\n}\n```\n\n### Installing into system directories\nAs an alternative to including the source files in your project directly,\nyou can use CMake to install the library in your system's include directory:\n\n```\nmkdir build\ncd build\ncmake ..\nmake install\n```\n\nThen, you can include it from your source code:\n```\n#include \u003creaderwriterqueue/readerwriterqueue.h\u003e\n```\n\n## Disclaimers\n\nThe queue should only be used on platforms where aligned integer and pointer access is atomic; fortunately, that\nincludes all modern processors (e.g. x86/x86-64, ARM, and PowerPC). *Not* for use with a DEC Alpha processor (which has very weak memory ordering) :-)\n\nNote that it's only been tested on x86(-64); if someone has access to other processors I'd love to run some tests on\nanything that's not x86-based.\n\n## More info\n\nSee the [LICENSE.md][license] file for the license (simplified BSD).\n\nMy [blog post][blog] introduces the context that led to this code, and may be of interest if you're curious\nabout lock-free programming.\n\n\n[blog]: http://moodycamel.com/blog/2013/a-fast-lock-free-queue-for-c++\n[license]: LICENSE.md\n[benchmarks]: http://moodycamel.com/blog/2013/a-fast-lock-free-queue-for-c++#benchmarks\n[gcc46bug]: http://stackoverflow.com/questions/16429669/stdatomic-thread-fence-has-undefined-reference\n[mpmc]: https://github.com/cameron314/concurrentqueue\n[circular]: readerwritercircularbuffer.h\n","funding_links":[],"categories":["TODO scan for Android support in followings","Concurrency","C++","Projects","Software"],"sub_categories":["Communication (RPC/threading/serialization)"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcameron314%2Freaderwriterqueue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcameron314%2Freaderwriterqueue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcameron314%2Freaderwriterqueue/lists"}