Monday 31 October 2016

Step by step multithreading : mutex


I am hoping that, you have understood previous topics mentioned in my web page, if not please go through them to understand this topic. Till now we have understood how to create thread. So simple and easy, isn't it? You made your program run faster, didn't you? of course you did, if you are running your program into multi-core processor and executing it through threads you are going to achieve the performance. 

Now lets move to the real issues, what if more then one threads are using same resource, simultaneously? This will result a messy output, this behavior will result into a disaster. Though your program become faster but it will not behave as per your expectations at run-time.

Lets understand it step by step, and learn how we can resolve it in C++. First look at below mentioned program and see what output it will produces -

#include<iostream>
#include<thread>
#include<string>
#include<vector>
using namespace std;

// student list
vector<string> studentList;
//teacher list
vector<string> teacherList;
void addStudentNames()
{
    studentList.push_back("studentA");
    studentList.push_back("studentB");
    studentList.push_back("studentC");
    studentList.push_back("studentD");
    studentList.push_back("studentE");
    studentList.push_back("studentF");
    studentList.push_back("studentG");
    studentList.push_back("studentH");
    studentList.push_back("studentI");
}

void addTeacherNames()
{
    teacherList.push_back("teacherListA");
    teacherList.push_back("teacherListB");
    teacherList.push_back("teacherListC");
    teacherList.push_back("teacherListD");
    teacherList.push_back("teacherListE");
    teacherList.push_back("teacherListF");
    teacherList.push_back("teacherListG");
    teacherList.push_back("teacherListH");
    teacherList.push_back("teacherListI");
}
void printStudentsName()
{
    for(auto const &student : studentList)
    {
        cout<< "Printing student names from thread - " << student << endl;
    }
}
void printTeachersName()
{
    for(auto const &teacher : teacherList)
    {
        cout<< "Printing teacher names from main thread - " << teacher << endl;
    }
}

int main(int argc, char **argv)
{
    addStudentNames();
    addTeacherNames();
    thread t1(printStudentsName);
    printTeachersName();
    t1.join();
    return 0;
}
/*
output -
$ ./a.exe
Printing teacher names from main thread - Printing student names from thread - teacherListAstudentA

Printing teacher names from main thread - Printing student names from thread - teacherListBstudentB

Printing teacher names from main thread - Printing student names from thread - teacherListCstudentC

Printing teacher names from main thread - Printing student names from thread - teacherListDstudentD

Printing teacher names from main thread - Printing student names from thread - teacherListEstudentE

Printing teacher names from main thread - Printing student names from thread - teacherListFstudentF

Printing teacher names from main thread - Printing student names from thread - teacherListGstudentG

Printing teacher names from main thread - Printing student names from thread - teacherListHstudentH

Printing teacher names from main thread - Printing student names from thread - teacherListIstudentI

*/

Look the output, is that what you was expecting? what is happening here? 

Actually child thread and main thread, both are sharing same resource (in this case cout), and both are running parallel. So both are printing their messages on screen and you get mixed result and all things just messed up, without caring what user/programmer expected it to be. How to solve that?

Well C++ standard library will give you mutex. which will help you solve above mentioned problem. See below mentioned code, followed by detailed discussion.

#include<iostream>
#include<thread>
#include<string>
#include<vector>
#include<mutex>
using namespace std;

// student list
vector<string> studentList;
//teacher list
vector<string> teacherList;
// declare mutex
std::mutex locker;

void addStudentNames()
{
    studentList.push_back("studentA");
    studentList.push_back("studentB");
    studentList.push_back("studentC");
    studentList.push_back("studentD");
    studentList.push_back("studentE");
    studentList.push_back("studentF");
    studentList.push_back("studentG");
    studentList.push_back("studentH");
    studentList.push_back("studentI");
}

void addTeacherNames()
{
    teacherList.push_back("teacherListA");
    teacherList.push_back("teacherListB");
    teacherList.push_back("teacherListC");
    teacherList.push_back("teacherListD");
    teacherList.push_back("teacherListE");
    teacherList.push_back("teacherListF");
    teacherList.push_back("teacherListG");
    teacherList.push_back("teacherListH");
    teacherList.push_back("teacherListI");
}
void printStudentsName()
{
    for(auto const &student : studentList)
    {
        locker.lock();
        cout<< "Printing student names from thread - " << student << endl;
        locker.unlock();
    }
}
void printTeachersName()
{
    for(auto const &teacher : teacherList)
    {
        locker.lock();
        cout<< "Printing teacher names from main thread - " << teacher << endl;
        locker.unlock();
    }
}

int main(int argc, char **argv)
{
    addStudentNames();
    addTeacherNames();
    thread t1(printStudentsName);
    printTeachersName();
    t1.join();
    return 0;
}
/*
output -

$ ./a.exe
Printing teacher names from main thread - teacherListA
Printing student names from thread - studentA
Printing teacher names from main thread - teacherListB
Printing student names from thread - studentB
Printing teacher names from main thread - teacherListC
Printing student names from thread - studentC
Printing teacher names from main thread - teacherListD
Printing student names from thread - studentD
Printing teacher names from main thread - teacherListE
Printing student names from thread - studentE
Printing teacher names from main thread - teacherListF
Printing student names from thread - studentF
Printing teacher names from main thread - teacherListG
Printing student names from thread - studentG
Printing teacher names from main thread - teacherListH
Printing student names from thread - studentH
Printing teacher names from main thread - teacherListI
Printing student names from thread - studentI
*/

Now we are locking shared resource, cout (which is shared between main and child thread). Mutex will allow you to do that. Until current thread unlock mutex, other thread will not get access to resource, cout.

So we lock the resource through mutex, which is shared between two or more threads. Mutex will protect your resource, it will avoid execution of resource by more then one thread simultaneously.

Congratulations, we have solved the first issue, now lets talk about second issue, (step by step we will solve all the issues, with code example). 

In any function, what if we lock resource and before control reaches to unlock(), we get exception? Well we have seen it while implementing join(), as what if we get exception before control reaches to join()

We have to use RAII, to solve above mentioned problem. look at the below mentioned code, and follow its description -

#include<iostream>
#include<thread>
#include<string>
#include<vector>
#include<mutex>
using namespace std;

// student list
vector<string> studentList;
//teacher list
vector<string> teacherList;
// declare mutex
std::mutex locker;

void addStudentNames()
{
    studentList.push_back("studentA");
    studentList.push_back("studentB");
    studentList.push_back("studentC");
    studentList.push_back("studentD");
    studentList.push_back("studentE");
    studentList.push_back("studentF");
    studentList.push_back("studentG");
    studentList.push_back("studentH");
    studentList.push_back("studentI");
}

void addTeacherNames()
{
    teacherList.push_back("teacherListA");
    teacherList.push_back("teacherListB");
    teacherList.push_back("teacherListC");
    teacherList.push_back("teacherListD");
    teacherList.push_back("teacherListE");
    teacherList.push_back("teacherListF");
    teacherList.push_back("teacherListG");
    teacherList.push_back("teacherListH");
    teacherList.push_back("teacherListI");
}
void printStudentsName()
{
    for(auto const &student : studentList)
    {
        lock_guard<mutex> nowLockWithGuard(locker);
        cout<< "Printing student names from thread - " << student << endl;
    }
}
void printTeachersName()
{
    for(auto const &teacher : teacherList)
    {
        // this will act as RAII.
        lock_guard<mutex> nowLockWithGuard(locker);
        cout<< "Printing teacher names from main thread - " << teacher << endl;
    }
}
// the best part of using lock_guard, is - now you don't have to unlock(). as soon as lock_guard goes
// out of control, it will get destroyed and that will invoke unlock().
int main(int argc, char **argv)
{
    addStudentNames();
    addTeacherNames();
    thread t1(printStudentsName);
    printTeachersName();
    t1.join();
    return 0;
}
/*
output -
$ ./a.exe
Printing teacher names from main thread - teacherListA
Printing student names from thread - studentA
Printing teacher names from main thread - teacherListB
Printing student names from thread - studentB
Printing teacher names from main thread - teacherListC
Printing student names from thread - studentC
Printing teacher names from main thread - teacherListD
Printing student names from thread - studentD
Printing teacher names from main thread - teacherListE
Printing student names from thread - studentE
Printing teacher names from main thread - teacherListF
Printing student names from thread - studentF
Printing teacher names from main thread - teacherListG
Printing student names from thread - studentG
Printing teacher names from main thread - teacherListH
Printing student names from thread - studentH
Printing teacher names from main thread - teacherListI
Printing student names from thread - studentI

*/


The best part of using RAII, you don't have to think about deleting or calling unlock(). As it will automatically get called, once RAII object goes out of scope.

Okay so we have discussed and solve two problems so far, related to mutex, now lets talk about the third problem

We are sharing global resource (cout), but what if some other thread use cout from somewhere else? as it is a global resource, any function call use it, from some corner of your project, isn't it?

In real scenario, please make sure your resource is limited to some scope (scope could be big or small, as per requirement, but it has to be in some scope, so that you can use mutex carefully). see below mentioned program for more detail (A simple class to get BD connection)-

#include<iostream>
#include<thread>
#include<mutex>
using namespace std;

class DB   // class responsible for all DB operation.
{
    public:
        execute(const string& str)
        {
            //execute the sql in respective DB
        }
};
class DBConnection
{
    public:
        DBConnection()
        {
            m_connection = new DB;
        }
        //execute your query 
        void executeYourQuery(const string& str)
        {
            lock_guard<mutex> lockedWithGuard(m_lock);
            m_connection->execute(str);
        }
    private:
        auto_ptr<DB> m_connection;
        std::mutex m_lock;
};

int main(int argc, char **argv)
{
    DBConnection connection;
    string input = "select * from emp;";
    connection.executeYourQuery(input);
    return 0;
}

Now your resource is secure, No one can get it without going through mutex (lock). As there is only one entry point, which is executeYourQuery() function, ideally cout is not a resource to put lock on, as it is global in true sense, you have to create resource and set few defined entry points, so that you have control on locking and unlocking it (acquiring DB connection class would be a very good example of resource, of may be a logfile class who log the runtime error message into a logfile, whatever you can think as a resource, fuel up your imagination and think about resource what you can relate better). Apart from that you have to careful for few things -

  1. Never return m_connection to out side world. To any function in any form (like returning handler and all, never do that with the resource, which you want to be thread safe).
  2. Dont pass m_connection to any user define function, he may copy that in global scope and use it, which will make your code not thread safe. Or he may delete m_connection, which will give you bad results at run time.
Okay so we have finally learnt how to protect our resource. Now the last but not the least issue (fourth problem statement)- "Your code is thread safe or not is depend upon the way you implement the business logic, even you have protected your resource 100% in your class " lets see this with a very simple example -

class Stack
{
    public:
        int pop();
        int top();
        void push();
        // and many more
    private:
        int *m_array;
        mutex m_mutex;
}

void SomeFunction(Stack& obj)
{
    int data = obj.top();
    obj.pop();
    SomeFunction2();
}

Think for a moment that, we have implemented our stack class, fully thread safe (if I put full implementation of stack class, then it will become very big, and my focus here is not implementing stack class, but to understand the implementation issues of mutex). So please focus on the business logic ( function - SomeFunction()), how our function is using thread safe class.

in above mentioned program, m_mutex will protect different thread to execute same function simultaneously, for ex function pop() will be executed once at a time from a thread. If we have 4 values in our container - 
                                                                    1 - top
                                                                    2
                                                                    3
                                                                    4
Think we have 2 threads, executing SomeFunction() function simultaneously, first thread will call top() and get value - 1, and at same time, second thread will call top, and this also get 1, now first thread calls pop() and delete 1, and second thread then call pop() and delete 2, hey but we never process 2 just deleted it, we were not interested to delete 2. it means this program is not thread safe.

Yes, this is not thread safe, because of the interface, the two function top and pop shall not be two atomic function, they should be part of a function. But still we can fix it by modifying the functions like mentioned below -

class Stack
{
    public:
        int pop();
        int top();
        void push();
        // and many more
    private:
        int *m_array;
        mutex m_mutex;
}

void SomeFunction(Stack& obj)
{
    // apply some business logic and check if you want to 
    // delete this number. if not want to delete then return;
    if(!doWeWantToDeleteThis(obj.top())
    {
        return;
    }
    obj.pop();
    SomeFunction2();
}

bool doWeWantToDeleteThis(int val)
{
    // implement some logic.
}

So there are 3 rues of using mutex efficiently -

  1. Use mutex to synchronize the resource.
  2. Never leak your data handler to outer world.
  3. Design your interface in such a way, it will become thread safe. Or implement your thread safe resource carefully.


Thanks for reading this, please write questions or some more useful information related to this topic on comment section. To learn more about threading, see the full learning index here, or join multithreading learning page on FB or on G++.

Wednesday 19 October 2016

Step by step multithreading : Functor

First understand what is functor? 
Any object who act like a function is called functor. The question here is how any object will act or look like function? Well if you have overload operator () in your class, you can give a look and feel of your object like a function, and we call it functor.

Till now we have seen, we pass function to thread object, but we can also pass functor to it - 
// we can also define functor
#include <iostream>
#include <thread>
using namespace std;

class PrintMe
{
    public:
        void operator()()
        {
            cout<<"Printing from thread, ";
        }
};

int main(int argc, char **argv)
{
    PrintMe functor1;
    thread t1(functor1);    // remember we use to pass function name here
                            // but we are passing an object, who looks like 
                            // function because of operator(). which make 
                            // it to print the message.
    t1.join();
    return 0;
}

/*
$ ./a.exe
Printing from thread,
*/

It is not necessary to create functor and pass it to thread, we can also call constructor while creating the thread object, like mentioned below -
// we can also define functor
#include <iostream>
#include <thread>
using namespace std;

class PrintMe
{
    public:
        void operator()()
        {
            cout<<"Printing from thread";
        }
};
int main(int argc, char **argv)
{
    thread t1((PrintMe())); // this will also work.
   t1.join();
    return 0;
}
/*
$ ./a.exe
Printing from thread
*/

Now the question is, can we pass any function parameter to functor, like we pass to functions? The answer is yes, we can pass parameter to functor, look at below code -
/*
even we can pass argument to functor.
*/
#include <iostream>
#include <thread>
using namespace std;

class PrintMe
{
    public:
        void operator()(string imput)
        {
            cout<<"Printing from thread"<<endl;
            cout<<"msg - "<< imput <<endl;
        }
};
int main(int argc, char **argv)
{
    string s1 = "Hello child thread ";
    thread t1((PrintMe()), s1);
    t1.join();
    return 0;
}
/*
$ ./a.exe
Printing from thread
msg - Hello child thread
*/

As C++ developer, I will think to pass my functor parameter by reference, to save extra works, like crating temp object, calling constructor and then destructor after it goes out of scope, etc. So I will write code where I will use pass by reference, like mentioned below -
/*
even we can pass argument to functor.
*/
#include <iostream>
#include <thread>
using namespace std;

class PrintMe
{
    public:
        void operator()(string& imput)
        {
            cout<<"Printing from thread"<<endl;
            cout<<"msg - "<< imput <<endl;
        }
};
int main(int argc, char **argv)
{
    string s1 = "Hello child thread ";
    thread t1((PrintMe()), s1);
    t1.join();
    return 0;
}

If I do that, I will get compilation error, as thread parameter cannot be passed as reference, you will get below mentioned compilation error -

functional:1505:61: error: no type named ‘type’ in ‘class std::result_of<PrintMe(std::basic_string<char>)>’

       typedef typename result_of<_Callable(_Args...)>::type result_type;

So the question is what we can do, if we want to pass parameter by reference. If we really willing to share the resource between parent thread and child thread, and want to pass it by reference, C++ standard library provide std::ref() function which will help to pass parameter by reference, look at below mentioned code for implementation -
/*
even we can pass argument to functor.
*/
#include <iostream>
#include <thread>
using namespace std;

class PrintMe
{
    public:
        void operator()(string& imput)
        {
            cout<<"Printing from thread"<<endl;
            cout<<"msg - "<< imput <<endl;
        }
};
int main(int argc, char **argv)
{
    string s1 = "Hello child thread ";
    thread t1((PrintMe()), std::ref(s1)); // this will work.
    t1.join();
    return 0;
}
/*
$ ./a.exe
Printing from thread
msg - Hello child thread
*/

We can check that, value is also being changed from child thread if you pass by reference, just to verify it, which is not possible through pass by value -
#include <iostream>
#include <thread>
#include <string>
using namespace std;

class PrintMe
{
    public:
        void operator()(string& imput)
        {
            cout<<"Printing from thread"<<endl;
            cout<<"msg - "<< imput <<endl;
            imput = "Modified the msg";
        }
};
int main(int argc, char **argv)
{
    string s1 = "Hello child thread ";
    thread t1((PrintMe()), std::ref(s1)); // this will also work.
    t1.join();
    
    cout<<"Printing it from main thread - "<<s1;
    return 0;
}
/*
$ ./a.exe
Printing from thread
msg - Hello child thread
Printing it from main thread - Modified the msg
*/

But sharing resources between threads are not always preferable, as there will be a chance that both threads can run and finish independently, without any dependency, and sometime it lead to memory related issues. In that case you just have to move resource from one thread to other thread, it is safe and efficient as well. After that, resource will belong to moved thread, C++ standard library provide std::move() function to do that, please have a look at below mentioned program -

/*
there are many things in C++ which can only be moved and not copied.

if we are not using any memory in main thread, we can move that 
memory to other thread who is looking for it, instead of sharing it.

because sharing will create data leak problems.
we can do pass by value, in that case, but that is not efficient, 
because then temp object creation/deletion will take place.

we can move the memory to other thread.
*/
#include <iostream>
#include <thread>
#include <string>
using namespace std;

class PrintMe
{
    public:
        void operator()(string imput)
        {
            cout<<"Printing from thread"<<endl;
            cout<<"msg - "<< imput <<endl;
            imput = "Modified the msg";
        }
};
int main(int argc, char **argv)
{
    string s1 = "Hello child thread ";
    thread t1((PrintMe()), std::move(s1)); // this will move thread from
                                           // main thread to child thread.
    t1.join();
    cout<<"Printing it from main thread - "<<s1;
    return 0;
}
/*
$ ./a.exe
Printing from thread
msg - Hello child thread
Printing it from main thread -
*/

Apart from moving the object from parent thread to child thread, we have to use std::move() when we are copying two threads. Actually we cannot copy the thread objects, it will give you compilation error. We can only move the thread objects from one object to another object, look at the below mentioned program, how we implement it - 

/*
thread cont be copied it can only be moved.
*/
#include <iostream>
#include <thread>
#include <string>
using namespace std;

class PrintMe
{
    public:
        void operator()(string imput)
        {
            cout<<"Printing from thread"<<endl;
            cout<<"msg - "<< imput <<endl;
            imput = "Modyfied the msg";
        }
};

int main(int argc, char **argv)
{
    string s1 = "Hello child thread ";
    thread t1((PrintMe()), std::move(s1)); 
    //thread t2 = t2            // this line of code will give me compilation error.
                                // but I can move the thread from one thread to another thread

    thread t2 = std::move(t1);  // we have to use move. 
                                // now t1 will be empty 

    t2.join();                  // call join in t2 now
    return 0;
}

Thanks for reading this, please write questions or some more useful information related to this topic on comment section. To learn more about threading, see the full learning index here, or join multithreading learning page on FB or on G++.

Tuesday 18 October 2016

Step by step multithreading : exceptions and threading.


First read below mentioned program -


#include <iostream>
#include <thread>
using namespace std;
void hello(); void foo() { thread t1(hello); //Do some work here, implement your business logic; t1.join(); } /* What if you get some exception in the function foo, before it join the thread t1. In that case thread will be disjoint. */ int main(int argc, char **argv) { foo(); return 0; }

void hello()
{
    cout<<"welcome to C++ multithreading";
}

As application developer you knew there is a possibility that any function who implements business logic can throw exceptions. What If function foo() throws any exception, before control reaches to t1.join(); ?

Then child thread t1 will never join parent thread. Which is not, what we want. We can solve this problem very well through try-catch blog (exception handling).

#include <iostream>
#include <thread>
using namespace std;
void hello(); void foo() { thread t1(hello); try { //Do some work here; } catch(...) { t1.join(); throw; } t1.join(); } /* we can solve that issue, with try catch block. */ int main(int argc, char **argv) { foo(); return 0; }

void hello()
{
    cout<<"welcome to C++ multithreading";
}

If any exception occurs, first we will join the thread in catch block, then throw the exception. By doing this we will achieve our intention of joining the child thread to parent thread.

Don't you feel doing this in every function, where you want to implement the thread, will become costly operation? As exception handling has a cost to implement, and your program will become slower compare to the version where you were not using exception handling.

Wait, think a second. Don't you feel that, you have seen this issue before? Yes, while dealing with pointers in C++. What if exception come and control don't reach to delete statement, then you will be facing memory leak issue as C++ don't provide garbage collector.

Remember, pointer issue? And how smartly we had solved that issue, by using smart pointers. Who will clean itself, if it goes out of control. Yes I am talking about RAII, which will help C++ developer to avoid memory leak. 

Look at the below mentioned program -
#include <iostream>
#include <thread>
using namespace std;
void hello(); /* we can also solve that issue by using RAII. crate a Wrapper class, in the destructor of Wrapper class join the thread.so as soon as it goes out of control it will call destructor and then join the thread. */ // a dummy class class ThreadWrapper { public: ThreadWrapper(thread& t); ~ThreadWrapper() { t.join(); } }; void foo() { //use RAIT ThreadWrapper w(thread t1(hello)); //Do some work here, implement your business logic; // now no need to call join here, as ThreadWrapper's // destructor will call it, as soon as it goes out of control. } int main(int argc, char **argv) { foo(); return 0; } void hello() { cout<<"welcome to C++ multithreading"; }

Note: this program is to understand the concept, actual ThreadWrapper class will have many other function in it, understand the intent right now, I will post full working code in some other blog.

Thanks for reading this, please write questions or some more useful information related to this topic on comment section. To learn more about threading, see the full learning index here, or join multithreading learning page on FB or on G++.

Thursday 13 October 2016

multithreading : thumb rules.


  1. If two threads are sharing same resource, then parent thread who own the resource, will wait for child thread to complete its work before termination.
  2. Once you join or detach the thread, you will not be able to join or detach it again. In C++, once you detach the thread and try to join it back to parent thread, you may end up with undefined behavior,  as a C++ programmer, you know that, most of the time undefined behavior means crash. So once thread is detach/join it will be in detach/join state forever, we can not detach/join it back again.
  3. How to calculate how many threads to create for my application?
    • Ideally as many numbers of cores are there in your processor.
    • We shall not create many threads, which our hardware can not handle, as too much context switching between threads will slow down the system. 
    • Also it is not strictly limited to the number of cores, as it is a good ides to go little higher (in numbers) then the actual number of cores, but higher has limit, otherwise you will end up with a problem as mentioned above (second point).
    • Thankfully in C++ we have a library function which will give you a very close idea about your hardware, it tells how many threads your hardware can handle easily - std::thread::hardware_concurrency(), so this function will give you answer.

Thanks for reading this, please write questions or some more useful information related to this topic on comment section. To learn more about threading, see the full learning index here, or join multithreading learning page on FB or on G++.

Step by step multithreading : Detach()


First read below mentioned program -


#include <iostream>
#include <thread>
using namespace std;

void hello();

int main(int arvc, char **argv)
{
    thread t1(hello);
    t1.detach(); //introducing detach, now thread t1 is independent of main thread
    return 0;
}

void hello()
{
    cout<<"welcome to C++ multithreading";
}


Detach - 

When parent thread is not willing to wait for child thread to finish, we can use detach(), in that case child thread can run independently. Then child thread will become a daemon process.

When you detach any thread, it means we are just saying it can run and terminate independently, now there will not be any guarantee which thread (between child and parent thread) will get finish early. 

Which thread will finish early? Will depend upon the way we have implemented our business logic or how much work individual thread has to do.

Thanks for reading this, please write questions or some more useful information related to this topic on comment section. To learn more about threading, see the full learning index here, or join multithreading learning page on FB or on G++.