Friday, February 16, 2024

My C++ exploration - concurrency - async and future - driven by the Intrinsic Motivation...



My whole professional life in the world of software was driven by Intrinsic Motivation.

Intrinsic motivation is the act of doing something without any obvious external rewards. You do it because it's enjoyable and interesting, rather than because of an outside incentive or pressure to do it, such as a reward or deadline.

An example of intrinsic motivation for a software engineer would be deciphering a piece of a framework code because you enjoy doing it and have an interest in the matter or subject, rather than doing it because you have to prove a point to others or pass an exam.

Intrinsic motivation comes from within, while extrinsic motivation arises from outside. When you’re intrinsically motivated, you engage in an activity solely because you enjoy it and get personal satisfaction from it.

Let's come back to the nitty gritty of C++.

Here's my exploration of the C++ async method from the future header.

C++ async is a function template from the <future> header that helps you execute functions asynchronously, potentially in separate threads. It returns a std::future object that you can use to track the progress and retrieve the result of the asynchronous task.

Key Concepts:

Asynchronous Execution: async launches the provided function in a different thread (or using other mechanisms) without blocking the calling thread. This allows your program to continue doing other work while the asynchronous task is running.

std::future: The std::future object returned by async serves as a placeholder for the result of the asynchronous task. You can use methods like get(), wait(), valid(), and ready() to manage and access the result.

Common Use Cases:

Performing I/O-bound operations (e.g., network requests, file reading/writing) without blocking the main thread.

Source Code:

/*


* Callback.h


*


* Created on: 28-Dec-2023


* Author: ridit


*/


#ifndef CALLBACK_H_

#define CALLBACK_H_


class CallBack {


public:


virtual void onStartTask() = 0;


virtual void onFinishTask() = 0;


};


#endif /* CALLBACK_H_ */


/*

* Caller.h

*

* Created on: Feb 15, 2024

* Author: som

*/


#ifndef CALLER_H_

#define CALLER_H_


#include <iostream>

#include "Callee.h"


using namespace std;


//forward declaration

class Callee;


class Caller : public CallBack{


private:


Callee* callee;


public:


Caller(){


    callee = new Callee(this);


}


void doOwnTask(){


    cout<<"Main thread id = " <<this_thread::get_id()<<endl;


    for(int i = 0;i<10;i++){


cout<<"Caller is doing its own task in the main thread..."<<endl;


}


}


void delegateTaskToCallee(){


callee->doBackgroundTask();


}


virtual ~Caller(){


}


void onStartTask(){


cout<<"The background task is starting"<<endl;


}


void onFinishTask(){

cout<<"The background task is finished. Thank you, Callee, for taking my burden"<<endl;


}


};


#endif /* CALLER_H_ */




/*

* Callee.h

*

* Created on: Feb 15, 2024

* Author: som

*/


#ifndef CALLEE_H_

#define CALLEE_H_


#include <iostream>

#include <future>

#include "CallBack.h"


using namespace std;


class Callee {


private:

CallBack* cb;


public:


Callee(CallBack* cb){


this->cb = cb;


}


virtual ~Callee(){


}


static bool task(){


cout<<"Background thread id = " <<this_thread::get_id()<<endl;


for(int i = 0;i<10;i++){

    cout<<"Callee is doing the background task"<<endl;

}


return true;


}


void doBackgroundTask(){


this->cb->onStartTask();


future<bool> futureTask = async(launch::async, Callee::task);


if(futureTask.get() == true){

    this->cb->onFinishTask();

    }


}


};


#endif /* CALLEE_H_ */




//============================================================================

// Name : Callback.cpp

// Author : Som

// Version :

// Copyright : som-itsolutions

// Description : Hello World in C++, Ansi-style

//============================================================================


#include <iostream>


#include "CallBack.h"


#include "Caller.h"


#include "Callee.h"


using namespace std;


int main() {


Caller* caller = new Caller();


caller->doOwnTask();


caller->delegateTaskToCallee();



return 0;


}



You may like my other research study vis-a-vis how the

evenlistener pattern has been implemented in Android UI input

events.


Here we go...


No comments: