At its core, the goal of a mutex is to exclude the possibility of simultaneous access so as to prevent data corruption, and to prevent crashes due to the use of non-thread-safe routines.
An example of where one would need to use a mutex is the following code:
#include <iostream>
#include <thread>
void worker(int i) {
std::cout << "Outputting this from thread number: " << i << "n";
}
int main() {
std::thread t1(worker, 1);
std::thread t2(worker, 2);
t1.join();
t2.join();
return 0;
}
If one were to try and run this preceding code as-is, one would notice that the text output from both threads would be mashed together instead of being output one after the other. The reason for this is that the standard output (whether C or C++-style) is not thread-safe. Though the application will not crash, the output will be a jumble.
The fix for this is simple, and is given as follows:
#include <iostream>
#include <thread>
#include <mutex>
std::mutex globalMutex;
void worker(int i) {
globalMutex.lock();
std::cout << "Outputting this from thread number: " << i << "n";
globalMutex.unlock();
}
int main() {
std::thread t1(worker, 1);
std::thread t2(worker, 2);
t1.join();
t2.join();
return 0;
}
In this situation, each thread would first need to obtain access to the mutex object. Since only one thread can have access to the mutex object, the other thread will end up waiting for the first thread to finish writing to the standard output, and the two strings will appear one after the other, as intended.