Boost named_mutex and remove () command

I have a class that can be created by multiple threads. But with one function, the code must be protected, so I decided to use the interprocess boost mutex. Each class creates or opens the same Mutex constructor in it:

MyClass::MyClass() { boost::interprocess::named_mutex m_Lock( boost::interprocess::open_or_create, "myLock" ); } 

So, the moment comes when the critical part of the code is called:

 int MyClass::MyFunction() { boost::interprocess::scoped_lock<boost::interprocess::named_mutex> lock( m_Lock, boost::interprocess::try_to_lock); if(!lock) { return -1; } // else do some stuff here } 

To clean up after the function (and as described above on the promotion page), I use the remove command in my class destructor:

 MyClass::~MyClass() { boost::interprocess::named_mutex::remove("myLock"); } 

Actually all this code works fine, but there is one problem:

As stated in the description of the remove command:

Removes a named mutex from the system. Returns false on error. Never quit.

Thus, the remove command simply removes Mutex from the system - even if another thread has just blocked it (I already tried this thing - it no longer blocks). So my problem is this: For example, I have 3 threads (A, B and C) - now the following happens:

  • Process A creates an instance of the class, calls the function, and blocks it
  • Process B instantiates the class, calls the function, but cannot access the code (then waits, for example,).
  • Process A ends with a secure code and it is unlocked.
  • Process B gains access to the protected code and blocks it.
  • Process A deletes an instance of the class -> the remove command is called
  • Process C creates an instance of the class, calls the function, and can access the code, as the remove command removes Mutex -> Error!

So now, someone might say, "Then don't call remove!" โ€œWell, is that possible?โ€ I mean, since named_mutex writes to the system, I doubt that it will be deleted without an explicit call, even if the program ends. Can anybody help?

+7
source share
2 answers

From boost docs, the remove call is not needed. The named_mutex destructor named_mutex automatically take care, indicating to the OS that the process no longer needs a resource. You probably just rely on the built-in behavior of the destructor to clean up.

If you explicitly call remove, you are likely to call any other processes or threads trying to use the named mutex to crash any operations on the mutex. Depending on how your use is organized, this can lead to data failure or crashes / exceptions that occur in other processes.

~ named_mutex ();

Kills * this and indicates that the call process has completed using the resource. The function of the destructor will free any system resources allocated by the system for use by this process for this resource. A resource can still be opened again, causing an open constructor overload. To remove a resource from the system, use delete ().

+6
source

You probably need a common usage counter for the mutex. Block the mutex in the destructor, reduce it, and if it is zero after decrement, release the locked mutex. You will prevent your current race condition.

0
source

All Articles