1

I want to use a shared mutex so threads only get locked when a vector/map/whatever is written to rather than read from. But I think func2() will never get the uniqueue lock because func1() will never get to unlock. Is there any way to not count a same-thread lock on shared_mutex when trying to get the uniqueue lock? Or would the problem still occur even then?

I'm guessing I need to find a way to force-get the lock (one thread at a time) once all threads have reached func2() OR have released the lock.

func2()
{
    boost::unique_lock<boost::shared_mutex> lock_access3(shared_mutex);
    /*stuff*/
    lock_access3.unlock(); 
}

func1()
{
    boost::shared_lock<boost::shared_mutex> lock_access1(shared_mutex);
    func2();
    lock_access1.unlock();
}
natli
  • 3,782
  • 11
  • 51
  • 82

2 Answers2

2

I believe you need to use a recursive mutex. See the good discussion on this question:

Boost provides this in the boost:recursive_mutex class.

Community
  • 1
  • 1
Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
0

Two things you need to do:

1) Since func1 implements a write operation, it needs to acquire an exclusive lock, not a shared lock.

2) Since func2 is called with the lock already held, it should not try to acquire the lock.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • func1 reads. After reading, it may or may not call func2() which will write. Still new to mutexes (and c++ in general) maybe the solution is really easy.. I just don't see it. – natli Jan 21 '12 at 05:33
  • So `func1` implements a write operation (a "maybe write" operation is a type of write operation.) That it does it by calling `func2` is irrelevant. Functions that perform write operations must acquire exclusive locks. – David Schwartz Jan 21 '12 at 05:34
  • What if func1 is extremely long? There would be no point for other threads to wait for it to finish if it isn't going to change the vector/map/heap that I'm trying to protect from getting corrupted in the first place. – natli Jan 21 '12 at 05:36
  • 1
    You have three choices: 1) You can hold an exclusive lock and see if the performance hit is significant. 2) You can use an upgradeable lock. (Which may not help as much as you'd expect.) 3) You can use an unlock and start over algorithm. (Take read lock, attempt operation, in unlikely case write is needed, release read lock, take write lock, start over -- if write is still needed, you're good since you hold the write lock anyway). – David Schwartz Jan 21 '12 at 05:38