Async Command Class In C++
Packaged task are IMO one of the most underutilized feature of C++ 11 standard. I have seen many blogs and many videos criticizing this feature for the lack of functionality it provides. Though its true that packaged tasks are a very small step towards achieving high level concurrency in C++, still whatever functionality it provides is heavily underutilized. In this blog I would attempt to model a pattern which I frequently encounter, using packaged tasks.
I am going to call the pattern Controller-Processor model. Controller thread wants some commands to be executed and Processor thread executes these commands. On the first glance it looks like Producer-Consumer model, but there is a subtle difference here. Unlike Producer-Consumer model, for every command send by the Controller thread it will expect a response from Processor thread.
One can use Callback functions to model this pattern. But Callback functions inverts the control flow of the programs and readability of the programs suffer. Moreover when using callback functions synchronization primitives must be used to ensure the response is correctly communicated. This makes the code complicated and error prone. Packaged Tasks are language feature which provides a elegant and simple way to address this problem.
I have created a generic command class which aims to model this pattern.
template<typename CommandType,typename ResponseType>
class AsyncCommandClass{
public:
explicit AsyncCommandClass(CommandType&& cmd) :
ComputeResult_{ [](ResponseType&& response) {return response;} }, Command{ cmd } {
}
std::future<ResponseType> getFuture() {
return ComputeResult_.get_future();
}
void sendResponse(ResponseType&& Response) {
ComputeResult_(std::move(Response));
}
CommandType Command; //! this represents actual command
private:
std::packaged_task<ResponseType(ResponseType&&)> ComputeResult_;
};
As it can be seen this generic class is just a wrapper around the packaged task. This class holds the command which a Controller sends to Processor. This class also has a method to retrieve future object which holds the result for this command.The Controller creates this Async Command and before sending it to Processor, it gets the future object which will give back the processed result.
The Processor thread receives this Command and executes the command. Once Command processing is complete it sends the response back to controller by calling "sendResponse" method.
So Controller just needs to send these Commands to Processor and need not wait for the response. It can continue doing other things. Whenever Controller wants to know the result it can get it from the future object. Unlike Callback functions the control flow is not inverted and all these functionalities are achieved with out using any explicit synchronization primitives.
To download this class and a usage example clone the git repository
https://github.com/selvakumarjawahar/AsyncCommand
Your feedback/Comments are welcome.