Mirroring Mutex

I have a thread question. It is known that basically when we call mutex (lock), this means that the thread continues to execute the part of the code that is continuous by other threads until it encounters the mutex (unlock). (At least what they say in the book) So my question is, is it actually possible to have multiple cloud WriteLocks that do not interfere with each other. For example, something like this:

If I have a buffer with N elements without any new elements, but with high-frequency updates (for example, changing the value of the Kth element), you can set a different lock for each element so that only the time flows stop and wait if 2 or more threads trying to update the same item?

+5
source share
5 answers

To answer your question about N mutexes: yes, it is really possible. What resources are protected by the mutex is entirely up to you as the user of this mutex.

This leads to the first (stated) part of your question. A mutex alone does not guarantee continuity of flow. All this guarantees is MUTual EXclusion - if thread B tries to lock a mutex that was blocked by thread A, thread B will block (not execute code) until thread A unlocks the mutex.

This means that mutexes can be used to ensure that a thread executes a block of code without interruption; but this only works if all threads follow the same mutex blocking protocol around this block of code. This means that you are responsible for assigning semantics (or values) to each individual mutex and properly observing the semantics in your code.

If you decide that the semantics will be “I have an array a of N data elements and an array m of N mutexes, and access to a[i] can only be done when m[i] locked”, then how it will work.

The need to consistently adhere to the same protocol is that you usually need to encapsulate the mutex and the code / data that it protects in the class in one way or another, so that the external code does not need the protocol details. He just knows: "Name this member function and synchronization will happen automatically." This "automagic" will be the class that implements the protocol accordingly.

+7
source

An important consideration when deciding between a mutex on an array and a mutex on an element is whether there are operations - for example, tracking the number of "used" elements of an array, an "active" element or moving a pointer to an object, an array to a larger buffer - this can be done only safe with one thread, and all the others are blocked.

Smaller, but sometimes important, consider the number of additional mutexes in memory.

If you really need to make such an update as soon as possible in a highly contested multithreaded program, you can also learn about atomic types of locks and their comparison and replacement / exchange operations, but I would recommend not to consider that if profiling an existing lock is not essential in your overall program performance.

+4
source

A mutex does not stop the execution of other threads completely, it only stops other threads from blocking the same mutex. That is, while one thread locks the mutex, the operating system continues to execute context switches, allowing other threads to start, but if any other thread tries to lock the same mutex, its execution will be stopped until the mutex will be unlocked.

So yes, you really can have several different mutexes and lock / unlock them yourself. Just beware of deadlocks, i.e. If one thread can block more than one mutex at a time, you may run into a situation where thread 1 has blocked mutex A and is trying to block mutex B, but is blocking because thread 2 has already blocked mutex B and it is trying to block mutex A ..

+1
source

It's not clear what your use case is:

  • threads get a buffer that is assigned to work
  • threads have some results and require a special buffer for updating.

In the first option, you need some assignment logic that assigns a buffer to the stream. This logic should be considered atomically. therefore, it is best to use a mutex to protect destination logic.

In another embodiment, it may be best to have a mutex vector, one for each buffer element.

In both cases, the buffer does not need to be protected, because it (or, better, each of its fields) is accessible from only one stream at a time.

You can also tell yourself about "semaphores." They contain a counter that allows you to manage ressources with a limited number, but more than one. Mutexes are a special case of semaphores with n = 1.

0
source

You can have a mutex for each record, a C ++ 11 mutex can easily be converted to adaptive spin lock so you can achieve a good compromise between processors and delays.

Or, if you need very low latency, but you have enough processors, you can use the atomic "busy" flag for each record and spin in a narrow exchange exchange cycle in case of conflict.

However, from experience, better performance and scalability are achieved when parallel writes are serialized through a command queue (or a queue of smaller immutable buffers for concatenation at the destination) and one thread processing the queue.
0
source

Source: https://habr.com/ru/post/1203363/


All Articles