Recall that std::lock_guard<M> and std::unique_lock<M> are parameterized on the mutex type. So far we've seen only std::mutex. However, the standard library does contain a few other mutex types which can be useful in special circumstances.
std::recursive_mutex is like std::mutex, but remembers which thread has locked it. If that particular thread tries to lock it a second time, the recursive mutex will merely increment an internal reference count of "how many times I've been locked." If some other thread tries to lock the recursive mutex, that thread will block until the original thread has unlocked the mutex the appropriate number of times.
std::timed_mutex is like std::mutex, but is aware of the passage of time. It has as member functions not only the usual .try_lock(), but also .try_lock_for() and .try_lock_until(...