This piece of code will perform std::vector zero tasks in a separate thread.
typedef std::vector<std::function< void() >> task_list; typedef std::chrono::high_resolution_clock::duration timing; typedef std::vector< timing > timing_result; timing_result do_tasks( task_list list ) { timing_result retval; for (auto&& task: list) { std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now(); task(); std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now(); retval.push_back( end-start ); } return retval; } std::future<timing_result> execute_tasks_in_order_elsewhere( task_list list ) { return std::async( std::launch::async, do_tasks, std::move(list) ); }
this should start each of the tasks sequentially outside the main thread and return std::future , which contains the synchronization results.
If you want temporary results to produce smaller fragments (i.e. before they were all ready), you will have to work harder. I would start with std::packaged_task and return std::vector<std::future< timing >> and from there.
The above code is untested / not compiled, but should not have fundamental flaws.
You will notice that the above does not use std::thread . std::thread is a low-level tool on which you should create tools from above, and not something that you should use directly (it is rather fragile due to the requirement that it be join ed or detach ed before destruction, among other things) .
While std::async nothing to write home, this is great for fast and messy multithreading, where you want to do a sequential task and do it "somewhere else." The lack of decent signaling via std::future makes it less complete (and this is the reason you might need to write higher level abstractions around std::thread ).
Here is one of them that will run a task sequence with a minimum delay between them:
#include <chrono> #include <iostream> #include <vector> #include <functional> #include <thread> #include <future> typedef std::chrono::high_resolution_clock::duration duration; typedef std::chrono::high_resolution_clock::time_point time_point; typedef std::vector<std::pair<duration, std::function< void() >>> delayed_task_list; void do_delayed_tasks( delayed_task_list list ) { time_point start = std::chrono::high_resolution_clock::now(); time_point last = start; for (auto&& task: list) { time_point next = last + task.first; duration wait_for = next - std::chrono::high_resolution_clock::now(); std::this_thread::sleep_for( wait_for ); task.second(); last = next; } } std::future<void> execute_delayed_tasks_in_order_elsewhere( delayed_task_list list ) { return std::async( std::launch::async, do_delayed_tasks, std::move(list) ); } int main() { delayed_task_list meh; meh.emplace_back( duration(), []{ std::cout << "hello world\n"; } ); std::future<void> f = execute_delayed_tasks_in_order_elsewhere( meh ); f.wait(); // wait for the task list to complete: you can instead store the `future` }
which the auxiliary async sleep thread should do for (at least as long as) the durations that you use before starting each task. As it is written, the time taken to complete each task is not taken into account with respect to delays, therefore, if tasks take longer than delays, you will ultimately complete tasks that are performed without delay between them. A change that should be easy if you want.