Presentation is loading. Please wait.

Presentation is loading. Please wait.

Advanced C++ Programming

Similar presentations


Presentation on theme: "Advanced C++ Programming"— Presentation transcript:

1 Advanced C++ Programming
Assignment 3 2016/2017 Přemysl Čech

2 Async tasks – continue with
Goal is to: implement the class task with functions implement global functions operating with task(s) Task represents an async call of a function on a new thread the motivation: we want to chain task(s) together the function „continue_with“ we want to comfortably control multiple running task(s)

3 Async tasks – continue with
template<class Ret> class task the template class – one parameter – a return type task(… f) (a constructor) - obtains a function f that will be called asynchronously on demand an evaluation doesn‘t start immediately! the function f is parameterless the return value of f has to match the return type of the class task functions start() – starts an async evaluation of the passed function f get_result() – returns a result of the function f (a blocking call) other functions that are not mandatory but might be useful has_started(), is_running(), …

4 Async tasks – continue with
template<class NRet> task<NRet> task<Ret>::continue_with(… g) obtains a new following function g that will be called after the original task is finished is also generic (templated) because the new function g can return a different value the continue_with(…) function returns a new task with the appropriate return value the input parameter of the function g has the same type as the result of the precedent (current) task (task(s) chaining) g obtains the result from the precedent task as the input value

5 Async tasks – continue with
Examples auto task1 = task<int>([]() { return 5; }).continue_with<int>([](int val) return val * 3; }).continue_with<void>([](int val) cout << "The result is: " << val << endl; }); //if not started, task starts task1.get_result(); //15 task<void> task1([]() { this_thread::sleep_for(chrono::milliseconds(2000)); cout << "Hello world!"; }); task1.start(); //wait for finish task1.get_result();

6 Async tasks – continue with
Examples int x = 0; auto t1 = task<int>([&]() { return x + 5; }); auto t2 = task<void>([&]() { cout << t1.get_result() << endl; }); auto t3 = task<void>([&]() { x = 10; }); t3.get_result(); t2.get_result(); //15 t2.get_result(); //output? Second output returns nothing – it does not call function again Functions can have captures assume a reasonable usage of all task(s)

7 Tasks – global functions
template<class T> void wait_all(vector<task<T>>& tasks) you don‘t have to keep this signature precisely the function obtains a vector (or a list or an array) of task(s) of the same return value and waits (a blocking call) until all task(s) are finished template<class T> size_t wait_any(vector<task<T>>& tasks) waits and returns the index of the first finished task

8 Tasks – global functions
template <class T> task<T> start_new(… f) creates a new task and starts it immediately template<class T> task<T> when_any(vector<task<T>>& tasks) obtains a vector of task(s) of the same return value returns a task with the value of the first finished task auto task1 = start_new<void>([]() { cout << "Hi!" << endl; });

9 Tasks – global functions
template<class T> task<vector<T>> when_all(vector<task<T>>& tasks) obtains a vector (or a list or an array) of task(s) of the same return value returns a task with results of all input task(s) (stored in a vector for example) an execution of all task(s) returned from functions does not start immediately (except start_new) they start after a start() or get_result() call

10 Tasks – global functions
when_all, when_any, wait_all, wait_any all functions start the passed task(s) (if not stared before) in „when“ case lazily! if some passed task(s) have already finished before calling a wait_any or when_any function an arbitrary task is returned first

11 Tasks – global functions
Examples auto tasks = vector<task<bool>> { start_new<bool>([]() { return is_prime( ); }), start_new<bool>([]() { return is_prime( ); }), start_new<bool>([]() { return is_prime( ); }) }; when_any(tasks).continue_with<void>([](bool val) { cout << "Computation of the first task has finished"; }).get_result(); when_all(tasks).continue_with<void>([](vector<bool>&& val) { cout << "Computation of all tasks have finished"; }).get_result(); wait_all(tasks); //just a check – should not block

12 Tasks and functions What to look for
void return type – is it a problem? probably you have to write some specializations passing and returning of all parameters l-value vs. r-value copying of task(s) – should be allowed the same running copied task should be evaluated only once all get_result() calls on the same copied task should return the same reference to the return value (the function is not executed again!) if the return value cannot be returned as a reference you don‘t have to check it (it‘s a users fault)

13 Tasks and functions Hints look at std::thread and std::future classes
they start immediately different forms of initialization (e.g. std::async) can be shared? you can use std::function for storing functions look at template specializations template<class T> class A { … }; template<> class A<int> { … };

14 Code and submissions You should follow best C++ practices
a proper naming, no duplicate code an effective parameters passing a correct allocation and deletion of all variables a reasonable distribution of your code into functions and classes also move an implementation code to the implementation file (.cpp) if possible Submit your final solution to the information system (SIS) two files – a .cpp and .hpp files write your name in a comment at the beginning of each file (//Jarda Vomacka)


Download ppt "Advanced C++ Programming"

Similar presentations


Ads by Google