Lock / Unlock Mutex Inside Private Functions

Imagine that you have a big function that locks / unlocks the mutex inside, and you want to break the function into smaller functions:

#include <pthread.h> class MyClass : public Uncopyable { public: MyClass() : m_mutexBuffer(PTHREAD_MUTEX_INITIALIZER), m_vecBuffer() {} ~MyClass() {} void MyBigFunction() { pthread_mutex_lock(&m_mutexBuffer); if (m_vecBuffer.empty()) { pthread_mutex_unlock(&m_mutexBuffer); return; } // DoSomethingWithBuffer1(); unsigned char ucBcc = CalculateBcc(&m_vecBuffer[0], m_vecBuffer.size()); // DoSomethingWithBuffer2(); pthread_mutex_unlock(&m_mutexBuffer); } private: void DoSomethingWithBuffer1() { // Use m_vecBuffer } void DoSomethingWithBuffer2() { // Use m_vecBuffer } private: pthread_mutex_t m_mutexBuffer; std::vector<unsigned char> m_vecBuffer; }; 

How do I lock / unlock a mutex inside smaller functions?

Do I have to unlock the mutex first, and then lock it immediately and finally unlock it before returning?

 void DoSomethingWithBuffer1() { pthread_mutex_unlock(&m_mutexBuffer); pthread_mutex_lock(&m_mutexBuffer); // Use m_vecBuffer pthread_mutex_unlock(&m_mutexBuffer); } 
+4
source share
2 answers

How do I lock / unlock a mutex inside smaller functions?

If your semantics require that your mutex be locked during the entire operation of MyBigFunction() , you cannot just unlock it and lock it in the middle of the function.

It would be best to ignore the mutex in the smaller DoSomethingWithBuffer...() functions and simply require that these functions be called with the mutex already locked. This should not be a problem since these functions are private.


On the other hand, the use of your mutex is incorrect: it is not safe for exceptions, and you have paths to codes in which you do not release the mutex. You must either use Mutex C ++ 11, or block classes or promotion equivalents if you use C ++ 03. In the worst case scenario, if you cannot use boost, write a small RAII wrapper to hold the lock.

+5
source

In general, try to keep the code regions within each lock to a minimum (to avoid competition), but avoid unlocking and immediately locking the same mutex. Thus, if smaller functions are not mutually exclusive, they should use their own independent methods and only when they really access the shared resource.

Another thing to keep in mind is to use RAII to lock and unlock (as in C ++ 11 with std::lock_guard<> ), so returning from a locked area (either directly or through an uncaught exception) does not leave you in locked state.

+2
source

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


All Articles