c++ - What is critical resources to a std::mutex object -
i new concurrency , having doubts in std::mutex
. i've int a; , books telling me declare mutex amut; exclusive access on a. question how mutex object recognizing critical resources has protect ? mean variable? i've 2 variables int a,b; declare mutex abmut; abmut protect what??? both , b or or b???
a std::mutex
not protect data @ all. mutex works this:
- when try lock mutex if mutex not locked, else wait until unlocked.
- when you're finished using mutex unlock it, else threads waiting forever.
how protect things? consider following:
#include <iostream> #include <future> #include <vector> struct example { static int shared_variable; static void incr_shared() { for(int = 0; < 100000; i++) { shared_variable++; } } }; int example::shared_variable = 0; int main() { std::vector<std::future<void> > handles; handles.reserve(10000); for(int = 0; < 10000; i++) { handles.push_back(std::async(std::launch::async, example::incr_shared)); } for(auto& handle: handles) handle.wait(); std::cout << example::shared_variable << std::endl; }
you might expect print 1000000000, don't have guarantee of that. should include mutex, this:
struct example { static int shared_variable; static std::mutex guard; static void incr_shared() { std::lock_guard<std::mutex>{ guard }; for(int = 0; < 100000; i++) { shared_variable++; } } };
so do? first of std::lock_guard
uses raii call mutex.lock()
when it's created , mutex.unlock
when it's destroyed, last 1 happens when leaves scope (here when function exits). in case 1 thread can executing loop because thread passes lock_guard
holds lock, , saw before no other thread can hold it. therefore loop safe. note put lock_guard
inside loop, might make program slow (locking , unlocking relatively expensive).
so in conclusion, mutex
protects blocks of code, in our example for-loop, not variable itself. if want variable protection, consider taking @ std::atomic
. following example example again unsafe because decr_shared
can called simultaneously thread.
struct example { static int shared_variable; static std::mutex guard; static void decr_shared() { shared_variable--; } static void incr_shared() { std::lock_guard<std::mutex>{ guard }; for(int = 0; < 100000; i++) { shared_variable++; } } };
this again safe, because variable protected, in code uses it.
struct example { static std::atomic_int shared_variable; static void decr_shared() { shared_variable--; } static void incr_shared() { for(int = 0; < 100000; i++) { shared_variable++; } } }; std::atomic_int example::shared_variable{0};
Comments
Post a Comment