{"id":19204732,"url":"https://github.com/hongtae/corodispatchqueue","last_synced_at":"2026-01-26T02:01:13.294Z","repository":{"id":244739732,"uuid":"815577417","full_name":"Hongtae/CoroDispatchQueue","owner":"Hongtae","description":"Simple Concurrency Library with Coroutine Dispatch Queue","archived":false,"fork":false,"pushed_at":"2024-08-13T03:09:59.000Z","size":37,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-21T13:03:19.389Z","etag":null,"topics":["async","async-await","asynchronous","asynchronous-programming","concurrency","concurrency-library","coroutines","cpp-coroutines","cpp-programming","cpp20","dispatchqueue","multithreading","parallelism","single-header-library","threadpool"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Hongtae.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":"2024-06-15T14:20:00.000Z","updated_at":"2024-12-27T08:14:45.000Z","dependencies_parsed_at":"2024-08-13T04:27:30.634Z","dependency_job_id":null,"html_url":"https://github.com/Hongtae/CoroDispatchQueue","commit_stats":null,"previous_names":["hongtae/corodispatchqueue"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Hongtae/CoroDispatchQueue","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hongtae%2FCoroDispatchQueue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hongtae%2FCoroDispatchQueue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hongtae%2FCoroDispatchQueue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hongtae%2FCoroDispatchQueue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Hongtae","download_url":"https://codeload.github.com/Hongtae/CoroDispatchQueue/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hongtae%2FCoroDispatchQueue/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28764403,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-26T00:37:26.264Z","status":"online","status_checked_at":"2026-01-26T02:00:08.215Z","response_time":59,"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":["async","async-await","asynchronous","asynchronous-programming","concurrency","concurrency-library","coroutines","cpp-coroutines","cpp-programming","cpp20","dispatchqueue","multithreading","parallelism","single-header-library","threadpool"],"created_at":"2024-11-09T13:09:32.840Z","updated_at":"2026-01-26T02:01:13.257Z","avatar_url":"https://github.com/Hongtae.png","language":"C++","readme":"# Cpp Coroutine Dispatch Queue\nC++ concurrency library with C++20 coroutines.\n\nThis project is a single header library.  \nJust include [\"DispatchQueue.h\"](DispatchQueue.h) in your project.  \n\nSee the example file for more details: [Sample code (test.cpp)](test.cpp)\n\n\u003e [!NOTE]  \n\u003e The sample project is for Visual Studio 2022.\n\n**Requires a C++20 or later compiler.**\n\n## Types\n- Task\n  - Common coroutine function type\n    ```\n    Task\u003cint\u003e getValue() {\n        co_return 1;\n    }\n\n    int n = co_await getValue();\n    ```\n    \n- Generator\n   - Function type that yields multiple values without returning\n     ```\n     Generator\u003cint\u003e gen(int n) {\n         for (int i = 0; i \u003c n; ++i)\n             co_yield i;\n     }\n\n     for (auto g = gen(10); co_await g; ) {\n         std::cout \u003c\u003c \"value: \" \u003c\u003c g.value();\n     }\n     ```\n- AsyncTask\n   - Asynchronous function type that runs on a specific dispatch queue.\n   - When it completes execution, it returns to the initial dispatch queue.\n     ```\n     AsyncTask\u003cint\u003e getValueThread() {\n         std::cout \u003c\u003c \"this_thread: \" \u003c\u003c std::this_thread::get_id();\n         co_return 0;\n     }\n\n     // Running on a background dispatch-queue and then returning to the original dispatch-queue.\n     // NOTE: Returning to the same dispatch queue does not mean the same thread.\n     //  If the current dispatch queue owns multiple threads, it may return to a different thread than it was before the call.\n     int value = getValueThread(); \n     ```\n- AsyncGenerator\n  - Asynchronous function type that runs on a specific dispatch queue.\n  - This function can yield multiple values to the caller without returning.\n    ```\n    AsyncGenerator\u003cint\u003e gen(int n) {\n        for (int i = 0; i \u003c n; ++i) {\n            std::cout \u003c\u003c \"callee-thread: \" \u003c\u003c std::this_thread::get_id();\n            co_yield i;\n        }\n    }\n\n    for (auto g = gen(10); co_await g; ) {\n        std::cout \u003c\u003c \"caller-thread: \" \u003c\u003c std::this_thread::get_id();\n        std::cout \u003c\u003c \"value: \" \u003c\u003c g.value();\n     }\n    ```\n- DispatchQueue\n   - A queue that manages threads. A queue can have multiple threads.\n   - See the source code for a detailed implementation.\n\n- TaskGroup\n   - Group object for executing coroutine functions in parallel\n\n- AsyncTaskGroup\n   - Group object for executing coroutine functions in parallel\n   - Runs on a specific dispatch queue and returns to the original dispatch queue when it completes.\n\n## Functions\n- detachTask(AsyncTask\u003cT\u003e)\n- detachTask(Task\u003cT\u003e)\n   - Run the coroutine.\n   - This function can be called in a synchronous context.\n      - This is the entry function that spawns the asynchronous context.\n\n- asyncSleep(double)\n   - Suspends execution for a given amount of time, but does not actually sleep the thread.\n\n- asyncYield()\n   - Yield execution to another coroutine function.\n\n- async(TaskGroup)\n- async(AsyncTaskGroup)\n   - Run a TaskGroup with multiple coroutine functions.\n\n## Usage\n```\n// async function using background thread.\nAsync\u003c\u003e func1() {\n    co_await asyncSleep(10.0);  // sleep 10s\n    co_return;\n}\n\n// async function that returns int.\nAsync\u003cint\u003e func2() {\n    int n = co_await doSomething();\n    co_return n;\n}\n\n// a coroutine function that returns float.\nTask\u003cfloat\u003e func3() {\n    co_return 1.0f;\n}\n```\n\n```\n// async generator to yield some values\nAsyncGenerator\u003cint\u003e asyncGen(int n) {\n    for (int i = 0; i \u003c n; ++i)\n        co_yield i;\n}\n\nauto x = asyncGen(10);\nwhile (co_await x) {\n    printf(\"yield: %d\", x.value());\n}\n```\n\n```\n\n// coroutine generator to yield INT values\nGenerator\u003cint\u003e generator(int n) {\n    for (int i = 0; i \u003c n; ++i)\n        co_yield i;\n}\n\nauto x = generator(3);\nwhile (co_await x) {\n    printf(\"yield: %d\", x.value());\n}\n```\n\n```\nAsync\u003c\u003e test() {\n    co_await asyncSleep(10.0);\n    co_return;\n}\n\n// run a new task in a background thread\ndispatchTask(test());\n\n// run multiple new tasks in a background thread\nauto group = AsyncTaskGroup{ test(), test(), test() }\nco_await async(group);\n```\n\n```\n// run multiple new tasks that return values in a background thread\nAsync\u003cint\u003e func1(int n) {\n    co_return n * 2;\n}\n\nauto group = AsyncTaskGroup({ func1(3), func1(10), func1(20) });\nauto x = co_await async(group);\nwhile (co_await x) {\n    printf(\"yield: %d\", x.value());\n}\n```\n\n```\n// switching the running task thread\n\nDispatchQueue myQueue(3);  // my queue with 3 threads\n\nAsync\u003c\u003e work() {\n    std::cout \u003c\u003c std::this_thread::get_id() \u003c\u003c std::end;\n\n    co_await myQueue;       // switching thread.\n\n    std::cout \u003c\u003c std::this_thread::get_id() \u003c\u003c std::end;\n\n    co_return;\n}\n```\n### Registering main thread\n- To use dispatchMain(), the main thread must be enabled.\n  ```\n  std::atomic_flag stop_running;\n  \n  int main() {\n      setDispatchQueueMainThread(); // Set the current thread as the main thread.\n\n     // activate main loop\n     auto\u0026 dq = DispatchQueue::main();\n     while (!stop_running.test()) {\n     if (dq.dispatcher()-\u003edispatch() == 0) {\n        dq.dispatcher()-\u003ewait();\n    }\n  }\n  ```\n\n## Tips \u0026 Tricks\n#### Using Win32 Main-thread as MainQueue\n- What if you can't control the main message loop?\n  - Use timer, run the following code once on the main thread.\n    ```\n    TIMERPROC timerProc = [](HWND, UINT, UINT_PTR, DWORD) {\n        auto\u0026 dq = dispatchMain();\n        while (dq.dispatcher()-\u003edispatch()) {}\n    };\n    setDispatchQueueMainThread();\n    SetTimer(nullptr, 0, USER_TIMER_MINIMUM, timerProc);\n    ```\n    - Install a timer in the main loop. With TIMEPROC, it is not affected by the modal-state of the Win32 message loop.\n    - Using Win32 Timer will result in a resolution of 10ms minimum, but we don't expect this to be a problem for asynchronous function execution in general.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhongtae%2Fcorodispatchqueue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhongtae%2Fcorodispatchqueue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhongtae%2Fcorodispatchqueue/lists"}