Tuesday, April 16, 2019

c++ Multithreading


1 Header Required:
#include <thread>

2 We can attach a callback with the std::thread object, that will be executed when this new thread starts.
These callbacks can be:
a.) Function Pointer
b.) Function Objects
c.) Lambda functions

3 Joining Threads with std::thread::join()
std::thread th(funcPtr);
th.join();

Detaching Threads using std::thread::detach()
std::thread th(funcPtr);
th.detach();

1.) Never call join() or detach() on std::thread object with no associated executing thread
2.) Never forget to call either join or detach on a std::thread object with associated executing thread

4 Pass Arguments to Threads
By default all arguments are copied into the internal storage of new thread.
Don’t pass addresses of variables from local stack to thread’s callback function.
Be careful while passing pointer to memory located on heap to thread. Because it might be possible that some thread deletes that memory before new thread tries to access it.
As arguments are copied to new threads stack so, if you need to pass references in common way.  ie.
   void threadCallback(int const & x)
   {
       int & y = const_cast<int &>(x);
       y++;
   }
   int main()
   {
    int x = 9;
    std::thread threadObj(threadCallback,std::ref(x));
    threadObj.join();
    return 0;
    }

Assigning pointer to member function of a class as thread function:
Pass the pointer to member function as callback function and pass pointer to Object as second argument.

#include <thread>
class DummyClass {
public:
    DummyClass()
    {}
    DummyClass(const DummyClass & obj)
    {}
    void sampleMemberFunction(int x)
    {
        std::cout<<"Inside sampleMemberFunction "<<x<<std::endl;
    }
};
int main() {

    DummyClass dummyObj;
    int x = 10;
    std::thread threadObj(&DummyClass::sampleMemberFunction,&dummyObj, x);
    threadObj.join();
    return 0;
}

5 std::mutex
There are two important methods of mutex:
a.) lock()
b.) unlock()
std::lock_guard
std::lock_guard is a class template, which implements the RAII RESOURCE ACQUISITION IS INITIALIZATION (RAII) for mutex.
It wraps the mutex inside it’s object and locks the attached mutex in its constructor. When it’s destructor is called it releases the mutex.

Condition Variables.
Condition Variable is a kind Event used for signaling between 2 threads. One thread can wait for it to get signaled, while other thread can signal this.

7std::future is a class template and its object stores the future value.
Now what the hell is this future value.
Actually a std::future object internally stores a value that will be assigned in future and it also provides a mechanism to access that value i.e. using get() member function. But if somebody tries to access this associated value of future through get() function before it is available, then get() function will block till value is not available.
std::promise is also a class template and its object promises to set the value in future. Each std::promise object has an associated std::future object that will give the value once set by the std::promise object.
A std::promise object shares data with its associated std::future object.

If std::promise object is destroyed before setting the value the calling get() function on associated std::future object will throw exception.
A part from this, if you want your thread to return multiple values at different point of time then just pass multiple std::promise objects in thread and fetch multiple return values from thier associated multiple std::future objects.

No comments:

Post a Comment