I have a struct instance that gets used by multiple threads. Each thread contains an unknown amount of function calls that alter the struct member variable.
I have a dedicated function that tries to "reserve" the struct instance for the current thread and I would like to ensure no other thread can reserve the instance till the original thread allows it.
Mutexes come to mind as those can be used to guard resources, but I only know of std::lock_guard that are in the scope of a single function, but do not add protection for all function calls in between lock and unlock.
Is it possible to protect a resource like that, when I know it will always call reserve and release in that order?
Snippet that explains it better:
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex
struct information_t {
std::mutex mtx;
int importantValue = 0;
// These should only be callable from the thread that currently holds the mutex
void incrementIt() { importantValue++; }
void decrementIt() { importantValue--; }
void reset() { importantValue = 0; }
} protectedResource; // We only have one instance of this that we need to work with
// Free the resource so other threads can reserve and use it
void release()
{
std::cout << "Result: " << protectedResource.importantValue << '\n';
protectedResource.reset();
protectedResource.mtx.unlock(); // Will this work? Can I guarantee the mtx is locked?
}
// Supposed to make sure no other thread can reserve or use it now anymore!
void reserve()
{
protectedResource.mtx.lock();
}
int main()
{
std::thread threads[3];
threads[0] = std::thread([]
{
reserve();
protectedResource.incrementIt();
protectedResource.incrementIt();
release();
});
threads[1] = std::thread([]
{
reserve();
// do nothing
release();
});
threads[2] = std::thread([]
{
reserve();
protectedResource.decrementIt();
release();
});
for (auto& th : threads) th.join();
return 0;
}