Types of mutexes and locks (C++)

Mutexes (Selection)
… synchronizes the access on critical sections

std::mutex Provides exclusive access (can only be pulled by one thread at a time and only once in that time)
std::recursive_mutex Provides exclusive access (can only be pulled by one thread at a time but infinitely often in that time)
std::shared_mutex Provides exclusive access (if pulled by a thread no other exclusive and no shared access possible) and shared access (if pulled by atleast one thread no exclusive but further shared access possible)

Locks (Selection)
… operates on a mutex for automatic locking

std::lock_guard Pulls the mutex from its construction til its destruction
std::unique_lock Pulls the mutex, but its interface allows to un/lock it manually as well (necessary for the usage of wait on conditional variables)
std::shared_lock Pulls a shared mutex for multiple access as long as no exclusive lock has been given by that mutex

Example

#include <string>
#include <thread>
#include <shared_mutex>

class FileIO
{
public:
  FileIO(std::string file) : m_file(file) {}
  void print() {
    std::shared_lock<std::shared_mutex> lock(m_smtx); // shared lock
    // print file
  }
  void write() {
    std::lock_guard<std::shared_mutex> lock(m_smtx); // exclusive lock
    // write file
  }
private:
  std::string m_file;
  std::shared_mutex m_smtx;
};