@ Niccolo
It is in fact my first multi-threaded program.
I tried reading stuffs ,but it dint stuck me ,and the best comment I ever read was, "try implementing your basic programs with threads".
now since you have already termed it a bad example ,I would request you to provide with good "study level " examples.
Form an vector of structures, where the structure contains two operands (doubles, integers, whatever you like), and a compatible 'result' member of appropriate type. Create several thousand with random values as the two operands (say, A and B).
Now, loop through the vector to call a member function which calculates a result from A and B, say R = A * B. The detail doesn't matter.
Make sure that works, and you can see the results.
Then, re-work the code to launch a few threads (2, 3 or matching your core count). Have each thread handle a portion of the vector for the calculation, so they run in parallel. For example, if you have 10,000 structures, and launch 4 threads, have each thread process 2500 of the structures (but not overlapping, first one does 0 to 24999, second does 25000 to 49999, etc).
Join the threads with the main (this synchronizes the main to continue after these 4 exit).
See that the results are the same.
Then, look into std::async (and the associated future) and see if you can alter the code to use that library for the same basic threaded design.
Another example is a serial number.
Fashion a global integer, set it to an arbitrary start point, and use it to "dispense" id numbers. In single threaded mode, test to make sure you can generate serial ID numbers and store them in a vector.
Then, expand that to issue serial ID numbers in several threads at once. If the global integer isn't protected, there will be duplicate ID's issued. Find a way to discover them (or prove there are none).
Then, look into both mutex and lock, and practice "protecting" the global integer so only 1 thread can issue and ID number at a time. See if you can eliminate any duplicates.
Finally, change from using a mutex and a lock and instead use a std::atomic<int> (a lock free approach that doesn't need a mutex and a lock).
BTW, the reason I said the example you chose would be "bad" is that linked lists are by nature not thread friendly containers. Most containers aren't friendly to threads, and generally one must ensure only one thread operates the container at a time.
One might be able to sequence through and "read-only" from a linked list in multiple threads, but not deleted from it or append to it. It becomes rather tricky to allow reading in multiple threads while restricting writing.