concurrency - How does a C++ std::mutex bind to a resource? -


does compiler check variables being modified between lock , unlock statements , bind them mutex there exclusive access them?

or mutex.lock() lock resources visible in current scope?

given m variable of type std::mutex:

imagine sequence:

int a; m.lock(); b += 1; = b; m.unlock(); do_something_with(a); 

there 'obvious' thing going on here:

the assignment of b , increment of b 'protected' interference other threads, because other threads attempt lock same m , blocked until call m.unlock().

and there more subtle thing going on.

in single-threaded code, compiler seek re-order loads , stores. without locks, compiler free re-write code if turned out more efficient on chipset:

int = b + 1; //    m.lock(); b = a; //    m.unlock(); do_something_with(a); 

or even:

do_something_with(++b); 

however, std::mutex::lock(), unlock(), std::thread(), std::async(), std::future::get() , on fences. compiler 'knows' may not reorder loads , stores (reads , writes) in such way operation ends on other side of fence specified when wrote code.

1: 2:    m.lock(); <--- fence 3:    b += 1;   <--- load/store operation may not move above line 2 4:    m.unlock(); <-- nor may moved below line 

imagine happen if wasn't case:

(reordered code)

thread1: int = b + 1;   <--- here thread precedes , executes same block of code   thread2: int = b + 1;   thread2: m.lock();   thread2: b = a;   thread2: m.unlock(); thread1: m.lock(); thread1: b = a; thread1: m.unlock(); thread1:do_something_with(a); thread2:do_something_with(a); 

if follow through, you'll see b has wrong value in it, because compiler tying make code faster.

...and that's compiler optimisations. std::mutex, etc. prevents memory caches reordering loads , stores in more 'optimal' way, fine in single-threaded environment disastrous in multi-core (i.e. modern pc or phone) system.

there cost safety, because thread a's cache must flushed before thread b reads same data, , flushing caches memory hideously slow compared cached memory access. c'est la vie. it's way make concurrent execution safe.

this why prefer that, if possible, in smp system, each thread has own copy of data on work. want minimise not time spent in lock, number of times cross fence.

i go on talk std::memory_order modifiers, dark , dangerous hole, experts wrong , in beginners have no hope of getting right.


Comments

Popular posts from this blog

serialization - Convert Any type in scala to Array[Byte] and back -

matplotlib support failed in PyCharm on OSX -

python - Matplotlib: TypeError: 'AxesSubplot' object is not callable -