How to use std::mutex

I'm having trouble understanding how I should use std::mutex. Most examples I found use only one mutex and it's declared at global scope, and we all know that's bad practice right?

What I understood is: whenever I want to access a shared resource(s) I lock a mutex assigned to control that resource(s) so that other threads will be blocked until I unlock it. Is this right? If it is, pairing up a mutex and a resource is just a matter of me remembering which mutex I use for which resource?
> If it is, pairing up a mutex and a resource is just a matter of me
> remembering which mutex I use for which resource?

It is a better idea to associate the two programmatically. For instance:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <mutex>

struct shared_resource 
{
    // ...
    void do_something() 
    {
        // access to instance restricted to one thread at a time
        std::lock_guard<std::mutex> lock( instance_lock ) ;

        // access non-static members
        // ...

        // access to static members restricted to one thread at a time
        {
            std::lock_guard<std::mutex> lock( class_lock ) ;
            // access static members
            // ...
        } // class_lock is released

        // ...

    } // instance_lock is released

    private: 
        std::mutex instance_lock ; // std::recursive_mutex
        static std::mutex class_lock ; // std::recursive_mutex
        
        // non-staic members
        // static members
};
In a case where I have, say, functions GetAnInt() and GetAFloat(), both nonstatic or static, I should have a mutex for each function right?
For get/set of an int, anything that can be wrapped in a std::atomic<>, a mutex is not required. Just make it a std::atomic<int>

http://en.cppreference.com/w/cpp/atomic/atomic

For more complex resources, one could use a mutex to serialize access. The typical usage should be one mutex to control all access to one resource. A simple approach is to use one mutex to control access to an object (through all functions) ie. treat the complete object as a single resource.
That means I can't directly use a member variable, I need to write a getter and a setter for each one right? (leaving aside std::atomic)
Last edited on
> That means I can't directly use a member variable
> I need to write a getter and a setter for each one right?

Yes. Assuming that your class is a simple unencapsulated type.

And the getters need to return by value.

In this case, for performance reasons, you might want to implement a reader-writer lock.
boost has a shared_mutex and an upgradable shared_lock<>.
As does C++14: http://en.cppreference.com/w/cpp/thread/shared_mutex
Alright, I think that's all I need to know for now, thank you very much for your help.
Topic archived. No new replies allowed.