{"id":30235029,"url":"https://github.com/artnum/mqueue","last_synced_at":"2025-08-30T02:04:47.523Z","repository":{"id":307482698,"uuid":"1029596665","full_name":"artnum/mqueue","owner":"artnum","description":"A multi-thread safe message queue in C","archived":false,"fork":false,"pushed_at":"2025-07-31T14:24:09.000Z","size":12,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-08-15T00:30:56.488Z","etag":null,"topics":["message-queue","thread-safe"],"latest_commit_sha":null,"homepage":"","language":"C","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/artnum.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null}},"created_at":"2025-07-31T09:28:32.000Z","updated_at":"2025-07-31T14:24:13.000Z","dependencies_parsed_at":"2025-07-31T15:22:29.642Z","dependency_job_id":"2ea726a0-4b8a-4777-a7e6-acd9a19698d6","html_url":"https://github.com/artnum/mqueue","commit_stats":null,"previous_names":["artnum/mqueue"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/artnum/mqueue","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artnum%2Fmqueue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artnum%2Fmqueue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artnum%2Fmqueue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artnum%2Fmqueue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/artnum","download_url":"https://codeload.github.com/artnum/mqueue/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artnum%2Fmqueue/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272793018,"owners_count":24993830,"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","status":"online","status_checked_at":"2025-08-30T02:00:09.474Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["message-queue","thread-safe"],"created_at":"2025-08-15T00:18:59.747Z","updated_at":"2025-08-30T02:04:47.487Z","avatar_url":"https://github.com/artnum.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# C Message Queue\n\nA simple, thread-safe message queue written in C using pthreads. This library provides a multi-producer, multi-consumer queue for inter-thread communication.\n\n-----\n\n## Description\n\nThis project implements a message queue that allows multiple threads to safely send and receive messages. It is designed to be a foundational component for concurrent applications where different parts of the program need to communicate asynchronously.\n\nThe queue supports:\n\n* **Multiple Producers**: Many threads can add messages to the queue simultaneously.\n* **Multiple Consumers**: Many threads can process messages from the queue.\n* **Direct-style messaging**: A requesting thread can wait for a specific response.\n\n-----\n\n## Design Choices\n\nSeveral key design choices were made to ensure thread safety and performance:\n\n* **Separate Input and Output Queues**: The system uses a single input queue for all incoming messages and a hash map of output queues for processed messages. This separates the concerns of adding new work and retrieving completed work, reducing contention.\n* **Fine-Grained Locking**: Instead of a single global lock, the queue uses multiple mutexes. There is one mutex for the input queue and an array of mutexes for the output queues. This allows multiple threads to access different parts of the queue concurrently, improving parallelism.\n* **Condition Variables for Efficient Waiting**: The implementation uses `pthread_cond_t` condition variables to avoid busy-waiting. Threads waiting for messages are put to sleep and are only woken up when a message is available, which is an efficient use of CPU resources.\n* **Atomic Operations**: Atomic variables are used for managing state like the `running` flag, the number of waiting threads, and the next message ID. This ensures that these values are updated safely and correctly in a multi-threaded context without requiring a mutex.\n* **Hash Map for Output**: Processed messages are stored in a hash map where the key is the message ID. This allows for a fast lookup of a specific message response. The size of this map can be configured at compile time.\n\n-----\n\n## Quick Start Example\n\nHere is a short example of how to use the message queue:\n\n```c\n#include \u003cstdio.h\u003e\n#include \u003cpthread.h\u003e\n#include \"src/include/mqueue.h\"\n\n// A simple worker thread that processes messages.\nvoid *worker_thread(void *queue) {\n    MQueue *q = (MQueue *)queue;\n    MQueueMessage *msg = mqueue_get_in(q);\n\n    if (msg) {\n        // Process the message (e.g., cast and use the data)\n        long my_data = (long)msg-\u003emessage;\n        printf(\"Worker processed message: %ld\\n\", my_data);\n\n        // In a real application, you might modify the message\n        // and add it to the output queue.\n        msg-\u003emessage = (uintptr_t)(my_data * 2);\n        mqueue_add_out(q, msg);\n    }\n    return NULL;\n}\n\nint main() {\n    // Create a new message queue\n    MQueue *queue = mqueue_create();\n\n    // Create a worker thread\n    pthread_t worker;\n    pthread_create(\u0026worker, NULL, worker_thread, queue);\n\n    // Add a message to the input queue\n    long message_data = 123;\n    int msg_id = mqueue_add_in(queue, (uintptr_t)message_data);\n    printf(\"Main thread added message with ID: %d\\n\", msg_id);\n\n    // Retrieve the processed message from the output queue\n    long processed_data = (long)mqueue_get_out(queue, msg_id);\n    printf(\"Main thread received processed message: %ld\\n\", processed_data);\n\n    // Clean up\n    pthread_join(worker, NULL);\n    mqueue_destroy(queue, NULL); // No special free function needed for long\n\n    return 0;\n}\n```\n\n### Compiling\n\nRemember to link against the pthreads library.\n\n```bash\ngcc -o my_app my_app.c mqueue.c -lpthread\n```\n\n-----\n\n## Useful Information\n\n* **`MQUEUE_HASH_MAP_SIZE`**: The size of the output hash map can be changed by defining `MQUEUE_HASH_MAP_SIZE` before including `mqueue.h`. A larger value might reduce collisions at the cost of more memory.\n* **`free_message`**: The `mqueue_destroy` function takes an optional function pointer `free_message` that will be called for any remaining messages in the queue. This is useful for freeing dynamically allocated message data to prevent memory leaks.\n* **Error Handling**: In a production application, you should add more robust error checking for the return values of the queue functions.\n\n-----\n\n## License\n\nThis project is licensed under the MIT License.\n\n```\nMIT License\n\nCopyright (c) 2025 Etienne Bagnoud\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```\n\n-----\n\n## This README.md was generated by Gemini\n\nThe C code for the message queue was human-written, but this explanatory `README.md` file was generated by Google's Gemini to provide clear and comprehensive documentation.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartnum%2Fmqueue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fartnum%2Fmqueue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartnum%2Fmqueue/lists"}