Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First task submitted in submitted task will not be scheduled. #160

Open
LCVitality opened this issue Mar 1, 2024 · 1 comment
Open

First task submitted in submitted task will not be scheduled. #160

LCVitality opened this issue Mar 1, 2024 · 1 comment

Comments

@LCVitality
Copy link

int main() {
    concurrencpp::runtime runtime;
    auto tpe = runtime.thread_pool_executor();
    auto result = tpe->submit([tpe]() {
        std::cout << "Main Task" << '\n' << std::flush;
        auto result1 = tpe->submit([]() { std::cout << "Task1" << '\n' << std::flush; });
        auto result2 = tpe->submit([]() { std::cout << "Task2" << '\n' << std::flush; });
        auto result3 = tpe->submit([]() { std::cout << "Task3" << '\n' << std::flush; });
        result1.get();
        result2.get();
        result3.get();
    });
    result.get();
}

the output would be:
Main Task
Task2
Task3

task1 would block thread forever unless I comment result1.get(), or add an empty task before task1.

@David-Haim
Copy link
Owner

David-Haim commented May 14, 2024

there is no bug, you just misused the library :)
You block in the threadpool and it is very wrong
from the documentation:

Waiting for a result to finish is a blocking operation (in the case the asynchronous result is not ready), and will suspend the entire thread of execution waiting for the asynchronous result to become available. Waiting operations are generally discouraged and only allowed in root-level tasks or in contexts which allow it, like blocking the main thread waiting for the rest of the application to finish gracefully, or using concurrencpp::blocking_executor or concurrencpp::thread_executor.

Correct code will be:

concurrencpp::result<void> function(concurrencpp::executor_tag, std::shared_ptr<concurrencpp::thread_pool_executor> tpe){
	std::cout << "Main Task" << '\n' << std::flush;
	auto result1 = tpe->submit([]() { std::cout << "Task1" << '\n' << std::flush; });
	auto result2 = tpe->submit([]() { std::cout << "Task2" << '\n' << std::flush; });
	auto result3 = tpe->submit([]() { std::cout << "Task3" << '\n' << std::flush; });
	co_await result1;
	co_await result2;
	co_await result3;	
}


int main() {
    concurrencpp::runtime runtime;
    auto tpe = runtime.thread_pool_executor();
    auto result = function({}, tpe);
    result.get();
}

we are using a parallel coroutine, to avoid returning result<result<void>> (and having to co_await co_await later on), and we use co_await inside the threadpool to avoid blocking.

Note that blocking in the main thread (result.get();) is ok, because we are waiting for our "real" application to finish. in any other case we need co_await, otherwise we defeat the purpose of task-based concurrency (which is about never blocking)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants