{"id":23460962,"url":"https://github.com/broucz/lf-queue","last_synced_at":"2025-04-12T04:19:35.203Z","repository":{"id":46115661,"uuid":"427627833","full_name":"broucz/lf-queue","owner":"broucz","description":"A lock-free multi-producer multi-consumer unbounded queue.","archived":false,"fork":false,"pushed_at":"2021-11-13T10:33:16.000Z","size":14,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-12T04:19:32.641Z","etag":null,"topics":["concurrency","data-structures","mpmc-queue","queue"],"latest_commit_sha":null,"homepage":"https://docs.rs/lf-queue/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/broucz.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-11-13T09:59:52.000Z","updated_at":"2022-09-11T15:16:20.000Z","dependencies_parsed_at":"2022-09-23T06:41:28.324Z","dependency_job_id":null,"html_url":"https://github.com/broucz/lf-queue","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/broucz%2Flf-queue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/broucz%2Flf-queue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/broucz%2Flf-queue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/broucz%2Flf-queue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/broucz","download_url":"https://codeload.github.com/broucz/lf-queue/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248514158,"owners_count":21116903,"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":["concurrency","data-structures","mpmc-queue","queue"],"created_at":"2024-12-24T07:26:36.789Z","updated_at":"2025-04-12T04:19:35.175Z","avatar_url":"https://github.com/broucz.png","language":"Rust","readme":"# lf-queue\n\n[![Crates.io](https://img.shields.io/crates/v/lf-queue)](https://crates.io/crates/lf-queue)\n[![Documentation](https://docs.rs/lf-queue/badge.svg)](https://docs.rs/lf-queue)\n[![Build Status](https://github.com/broucz/lf-queue/workflows/CI/badge.svg)](https://github.com/broucz/lf-queue/actions/workflows/ci.yml?query=branch%3Amain)\n[![MIT licensed](https://img.shields.io/crates/l/lf-queue)](LICENSE)\n\nA lock-free multi-producer multi-consumer unbounded queue.\n\n## Examples\n\n```toml\n[dependencies]\nlf-queue = \"0.1\"\n```\n\nSingle Producer - Single Consumer:\n\n```rust\nuse lf_queue::Queue;\n\nfn main() {\n    const COUNT: usize = 1_000;\n    let queue: Queue\u003cusize\u003e = Queue::new();\n\n    for i in 0..COUNT {\n        queue.push(i);\n    }\n\n    for i in 0..COUNT {\n        assert_eq!(i, queue.pop().unwrap());\n    }\n\n    assert!(queue.pop().is_none());\n}\n```\n\nMulti Producer - Single Consumer:\n\n```rust\nuse lf_queue::Queue;\nuse std::thread;\n\nfn main() {\n    const COUNT: usize = 1_000;\n    const CONCURRENCY: usize = 4;\n\n    let queue: Queue\u003cusize\u003e = Queue::new();\n\n    let ths: Vec\u003c_\u003e = (0..CONCURRENCY)\n        .map(|_| {\n            let q = queue.clone();\n            thread::spawn(move || {\n                for i in 0..COUNT {\n                    q.push(i);\n                }\n            })\n        })\n        .collect();\n\n    for th in ths {\n        th.join().unwrap();\n    }\n\n    for _ in 0..COUNT * CONCURRENCY {\n        assert!(queue.pop().is_some());\n    }\n\n    assert!(queue.pop().is_none());\n}\n```\n\nSingle Producer - Multi Consumer:\n\n```rust\nuse lf_queue::Queue;\nuse std::thread;\n\nfn main() {\n    const COUNT: usize = 1_000;\n    const CONCURRENCY: usize = 4;\n\n    let queue: Queue\u003cusize\u003e = Queue::new();\n\n    for i in 0..COUNT * CONCURRENCY {\n        queue.push(i);\n    }\n\n    let ths: Vec\u003c_\u003e = (0..CONCURRENCY)\n        .map(|_| {\n            let q = queue.clone();\n            thread::spawn(move || {\n                for _ in 0..COUNT {\n                    loop {\n                        if q.pop().is_some() {\n                            break;\n                        }\n                    }\n                }\n            })\n        })\n        .collect();\n\n    for th in ths {\n        th.join().unwrap();\n    }\n\n    assert!(queue.pop().is_none());\n}\n\n```\n\nMulti Producer - Multi Consumer:\n\n```rust\nuse lf_queue::Queue;\nuse std::sync::atomic::{AtomicUsize, Ordering};\nuse std::sync::Arc;\nuse std::thread;\n\nfn main() {\n    const COUNT: usize = 1_000;\n    const CONCURRENCY: usize = 4;\n\n    let queue: Queue\u003cusize\u003e = Queue::new();\n    let items = Arc::new((0..COUNT).map(|_| AtomicUsize::new(0)).collect::\u003cVec\u003c_\u003e\u003e());\n\n    let ths: Vec\u003c_\u003e = (0..CONCURRENCY)\n        .map(|_| {\n            let q = queue.clone();\n            let its = items.clone();\n            thread::spawn(move || {\n                for _ in 0..COUNT {\n                    let n = loop {\n                        if let Some(x) = q.pop() {\n                            break x;\n                        } else {\n                            thread::yield_now();\n                        }\n                    };\n                    its[n].fetch_add(1, Ordering::SeqCst);\n                }\n            })\n        })\n        .map(|_| {\n            let q = queue.clone();\n            thread::spawn(move || {\n                for i in 0..COUNT {\n                    q.push(i);\n                }\n            })\n        })\n        .collect();\n\n    for th in ths {\n        th.join().unwrap();\n    }\n\n    thread::sleep(std::time::Duration::from_millis(10));\n\n    for c in \u0026*items {\n        assert_eq!(c.load(Ordering::SeqCst), CONCURRENCY);\n    }\n\n    assert!(queue.pop().is_none());\n}\n```\n\n## Acknowledgement\n\nThis implementation of a lock-free queue in Rust took inspiration from the [`concurrent-queue`](https://github.com/smol-rs/concurrent-queue) crate and aims to be used for educational purposes. The code documentation help you to discover the algorithm used to implement a concurrent lock-free queue in Rust, but might not yet be beginner-friendly. More details and learning materials will be added over time.\n\n## License\n\nThis project is licensed under the [MIT license](LICENSE).\n\n## Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, shall be licensed as above, without any additional\nterms or conditions.\n\nNote that, as of now, my focus is on improving the documentation of this crate, not adding any additional feature. Please open an issue and start a discussion before working on any significant PR.\n\nContributions are welcome.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbroucz%2Flf-queue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbroucz%2Flf-queue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbroucz%2Flf-queue/lists"}