{"id":21984279,"url":"https://github.com/konvt/threadpool","last_synced_at":"2025-10-15T07:38:35.508Z","repository":{"id":197233682,"uuid":"698238642","full_name":"Konvt/ThreadPool","owner":"Konvt","description":"A straightforward implementation of a C++17 thread pool.","archived":false,"fork":false,"pushed_at":"2023-11-27T09:05:46.000Z","size":20,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-23T01:44:02.735Z","etag":null,"topics":["cpp","cpp17","thread-pool","threadpool"],"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/Konvt.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}},"created_at":"2023-09-29T13:19:51.000Z","updated_at":"2023-11-09T02:14:13.000Z","dependencies_parsed_at":null,"dependency_job_id":"69661c03-4f98-4d8b-acbf-32c8b9cca4bd","html_url":"https://github.com/Konvt/ThreadPool","commit_stats":null,"previous_names":["konvt/threadpool"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/Konvt/ThreadPool","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Konvt%2FThreadPool","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Konvt%2FThreadPool/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Konvt%2FThreadPool/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Konvt%2FThreadPool/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Konvt","download_url":"https://codeload.github.com/Konvt/ThreadPool/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Konvt%2FThreadPool/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279059617,"owners_count":26094993,"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-10-15T02:00:07.814Z","response_time":56,"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":["cpp","cpp17","thread-pool","threadpool"],"created_at":"2024-11-29T18:08:20.469Z","updated_at":"2025-10-15T07:38:35.459Z","avatar_url":"https://github.com/Konvt.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ThreadPool-cpp17\n\n**Contents**  \n- [ThreadPool-cpp17](#threadpool-cpp17)\n  - [Example usage](#example-usage)\n  - [Create thread pool](#create-thread-pool)\n  - [Exception handle](#exception-handle)\n  - [Available interface](#available-interface)\n- [ThreadPool-cpp17-zh\\_cn](#threadpool-cpp17-zh_cn)\n  - [使用例](#使用例)\n  - [创建线程池](#创建线程池)\n  - [异常处理](#异常处理)\n  - [可用的接口](#可用的接口)\n\nA straightforward implementation of a C++17 thread pool.\n\n`ThreadPool` provides a thread pool with a shared task queue, allowing multiple threads to work on a single queue of tasks.\n\n`MultiplePool` provides a thread pool where each thread has its own task queue. Task dispatching is achieved by calling private method `dispatch`.\n\nEach thread pool offers similar interfaces, including two optional exception handling methods. And both of them depend on 'SafeQueue.hpp'.\n\n## Example usage\n```cpp\n#include \u003ciostream\u003e\n#include \u003cmutex\u003e\n#include \u003cchrono\u003e\n#include \"MultiplePool.hpp\"\n\nstd::mutex mtx;\n\nvoid task(int id) {\n    {\n        std::lock_guard\u003cstd::mutex\u003e lock {mtx};\n        std::cout \u003c\u003c \"Task \" \u003c\u003c id \u003c\u003c \" started\" \u003c\u003c std::endl;\n    }\n    std::this_thread::sleep_for(std::chrono::seconds(1));\n    {\n        std::lock_guard\u003cstd::mutex\u003e lock {mtx};\n        std::cout \u003c\u003c \"Task \" \u003c\u003c id \u003c\u003c \" completed\" \u003c\u003c std::endl;\n    }\n}\n\nint main()\n{\n    Gadgetry::MultiplePool thread_pool;\n\n    for (int i=1; i\u003c=10; ++i) {\n        thread_pool.submit(task, i);\n    }\n\n    thread_pool.shutdown();\n    std::cout \u003c\u003c \"All tasks completed\" \u003c\u003c std::endl;\n}\n```\n\n## Create thread pool\nThe constructor requires two optional default parameters.\n\nThe first one is used to specify the number of threads in the thread pool, while the second one is used to specify the exception handling approach of the thread pool. Once the parameters are specified, they cannot be changed.\n\nWhen not explicitly specified, the second parameter is set to `MultiplePool::preserve`, and the first parameter is obtained by calling `std::thread::hardware_concurrency()`, which retrieves the maximum number of threads supported by the underlying hardware.\n```cpp\nexplicit MultiplePool(\n    const std::size_t size = std::thread::hardware_concurrency(),\n    MultiplePool::ErrorLevel handle_type = MultiplePool::preserve\n)   : _task_list{size}, _workers{size}, handler{handle_type}, _shutdown{false}, _stop_submit{false} {\n    std::size_t i = 0; // thread ID starts from zero\n    for (auto\u0026 thread : _workers)\n        thread = std::thread(MultiplePool::Worker(this, i++));\n}\n```\n\n## Exception handle\nBoth thread pools employ the same exception handling approach, using `MultiplePool` as an example:\n\nIf `MultiplePool::ignore` is used, it means that when a thread encounters an exception, it will be caught and discarded without any further action.\n\nIf `MultiplePool::preserve` is used, it means that when a thread encounters an exception, it will be caught and stored in a message queue. Later, all these exceptions can be rethrown by invoking `rethrow_errors` method.\n\nIt is safe to invoke `rethrow_errors` when no exceptions occurred.\n\n## Available interface\n- `std::size_t get_thread_count()`\n  Returns the number of threads in the thread pool.\n\n- `void rethrow_errors()`\n  Rethrows the stored exceptions when the error level is `MultiplePool::preserve`.\n\n- `void shutdown()`\n  Shutdown the thread pool, stop accepting new tasks and wait for all tasks to complete.\n\n- `template\u003ctypename F, typename... Args\u003e auto submit(F\u0026\u0026 tsk, Args\u0026\u0026 ...args) -\u003e std::future\u003cstd::invoke_result_t\u003cF, Args...\u003e\u003e`\n  Submits task to thread pool, an exception `bad_submit` will be throw if the thread pool is closed.\n\n- `template\u003ctypename F, typename... Args\u003e auto submit(std::optional\u003cstd::size_t\u003e thread_id, F\u0026\u0026 tsk, Args\u0026\u0026 ...args) -\u003e std::future\u003cstd::invoke_result_t\u003cF, Args...\u003e\u003e`\n  Submits the task to the specified thread for execution, an exception `bad_submit` will be throw if the thread pool is closed, another exception `bad_thread_id` will be throw if the specified thread ID is out of the number of threads. **This method only available in `MutiplePool`.**\n- - -\n\n# ThreadPool-cpp17-zh_cn\n基于 C++17 的线程池简单实现。\n\n`ThreadPool` 提供了一个带有共享任务队列的线程池，允许多个线程共享同一个任务队列.\n\n\n`MultiplePool` 中每个线程都有自己的任务队列. 不显式指定线程 id 时任务派发由私有方法 `dispatch` 决定.\n\n每个线程池都提供类似的接口，其中包括两个相同的可选异常处理方法. 两个线程池都依赖于 SafeQueue.hpp.\n\n## 使用例\n```cpp\n#include \u003ciostream\u003e\n#include \u003cmutex\u003e\n#include \u003cchrono\u003e\n#include \"MultiplePool.hpp\"\n\nstd::mutex mtx;\n\nvoid task(int id) {\n    {\n        std::lock_guard\u003cstd::mutex\u003e lock {mtx};\n        std::cout \u003c\u003c \"Task \" \u003c\u003c id \u003c\u003c \" started\" \u003c\u003c std::endl;\n    }\n    std::this_thread::sleep_for(std::chrono::seconds(1));\n    {\n        std::lock_guard\u003cstd::mutex\u003e lock {mtx};\n        std::cout \u003c\u003c \"Task \" \u003c\u003c id \u003c\u003c \" completed\" \u003c\u003c std::endl;\n    }\n}\n\nint main()\n{\n    Gadgetry::MultiplePool thread_pool;\n\n    for (int i=1; i\u003c=10; ++i) {\n        thread_pool.submit(task, i);\n    }\n\n    thread_pool.shutdown();\n    std::cout \u003c\u003c \"All tasks completed\" \u003c\u003c std::endl;\n}\n```\n\n## 创建线程池\n构造函数接受两个可选的参数.\n\n第一个参数用于指定线程池中的线程数，第二个参数用于指定线程池的异常处理方法. 参数一旦指定就不能更改.\n\n当参数缺省时，第二个参数会被设置为 `MultiplePool::preserve`，第一个参数会被设置为 `std::thread::hardware_concurrency()` 的返回值，这个函数会返回底层支持的最大线程数.\n```cpp\nexplicit MultiplePool(\n    const std::size_t size = std::thread::hardware_concurrency(),\n    MultiplePool::ErrorLevel handle_type = MultiplePool::preserve\n)   : _task_list{size}, _workers{size}, handler{handle_type}, _shutdown{false}, _stop_submit{false} {\n    std::size_t i = 0; // thread ID starts from zero\n    for (auto\u0026 thread : _workers)\n        thread = std::thread(MultiplePool::Worker(this, i++));\n}\n```\n\n## 异常处理\n两个线程池采用了相同的异常处理代码，这里以 `MultiplePool` 为例：\n\n如果使用 `MultiplePool::ignore`，线程在遇到异常时会直接捕获并抛弃，假装无事发生.\n\n如果使用 `MultiplePool::preserve`，那么被捕获的异常会被存储在消息队列中. 稍后可以通过调用 `rethrow_errors` 方法重新抛出这些异常.\n\n没有异常发生时调用 `rethrow_errors` 是安全的.\n\n## 可用的接口\n- `std::size_t get_thread_count()`\n  返回线程池中的线程数量.\n\n- `void rethrow_errors()`\n  如果异常处理等级是 `MultiplePool::preserve` 时会重新抛出所有捕获到的异常.\n\n- `void shutdown()`\n  关闭线程池，停止接受任务并等待所有任务处理完毕.\n\n- `template\u003ctypename F, typename... Args\u003e auto submit(F\u0026\u0026 tsk, Args\u0026\u0026 ...args) -\u003e std::future\u003cstd::invoke_result_t\u003cF, Args...\u003e\u003e`\n  将任务提交给线程池，线程池已关闭时提交会抛出异常 `bad_submit`.\n\n- `template\u003ctypename F, typename... Args\u003e auto submit(std::optional\u003cstd::size_t\u003e thread_id, F\u0026\u0026 tsk, Args\u0026\u0026 ...args) -\u003e std::future\u003cstd::invoke_result_t\u003cF, Args...\u003e\u003e`\n  将任务提交给线程池中的指定线程，线程池已关闭时提交会抛出异常 `bad_submit`，指定的线程 id 超出了线程数量范围时会抛出异常 `bad_thread_id`. **这个方法仅适用于 `MutiplePool`.**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkonvt%2Fthreadpool","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkonvt%2Fthreadpool","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkonvt%2Fthreadpool/lists"}