Sign in to follow this  
noatom

lock guard for mutex scoping question

Recommended Posts

noatom    927

Im facing a small problem: a locked mutex by guard, means that the mutex will only be unlocked once the end of the scope is reached. Something like:

void work(string& file){

mutex m;

lock_guard<mutex> guard(m);

//edit the file string without worry, since the shared memory is now locked

//now start doing other important work which does not involve altering file in any way

}

The guard will only go out of scope and unlock the file string memory when the function ends.

 

So if i instantiate 4 threads with that function, using the same string as argument for all of them,wouldn't the threads wait one after the other, since the file string is locked for the ENTIRE duration of the work function?

Edited by noatom

Share this post


Link to post
Share on other sites
Zipster    2365

You can create a nested scope inside the function for only the duration that you need the lock:

mutex m;

void work(string& file)
{
   // pre-lock stuff

   {
      lock_guard<mutex> guard(m);

      // lock stuff, guard will go out of scope before the post-lock stuff
   }

   // post-lock stuff
}

However if you can avoid the locks completely, that would be ideal smile.png As you said, each thread would have to wait for any other thread that holds the lock to complete its work. Even then, you can risk starvation if the same lucky thread wins the lock each time. The nested scope only mitigates this by locking just the section of code that needs synchronization.

Edited by Zipster

Share this post


Link to post
Share on other sites
noatom    927

Ok, good idea. Though, I would have to look a shared memory resource, even when just reading and not modifying any sort of data from it, right? Since another thread might be changing something in that resource at that very moment.

Edited by noatom

Share this post


Link to post
Share on other sites
Zipster    2365

That really depends on the resource. As long as it remains immutable to all threads with concurrent access, you'll probably be safe not synchronizing access to it. However you almost always need to rely on documentation to know which operations are thread-safe and which aren't.

 

An std::string in particular doesn't make any guarantees about thread-safety (same situation with most of the standard library*), so you definitely don't want more than one thread accessing it at once, even for ostensibly read-only operations like c_str(). This doesn't necessarily mean that you need to fall-back on locks, but without more information on what you're trying to do, it's hard to suggest better alternative.

 

* There are some implementations that guarantee std::string is thread-safe, but you generally don't want to target specific implementations of the standard library unless you never intend on porting your code to a different platform/compiler/version/etc.

Share this post


Link to post
Share on other sites
phil_t    8084
If all you're trying to do is guard access to a std::string, why not just pass copies of it to these functions? Then you don't need any synchronization.

Share this post


Link to post
Share on other sites
alh420    5995


If all you're trying to do is guard access to a std::string, why not just pass copies of it to these functions? Then you don't need any synchronization.

 

Also, if this is not a working approach, since some threads will be writing to parts of the string, and other threads will be reading the same parts of that string, then your algorithm isn't very suitable to multithread in the first place, and you might want to take a step back and redesign it.

Share this post


Link to post
Share on other sites
SmkViper    5396
First - dunno if your source in the OP is accurate to what is in your code, but your mutex in your example won't lock anything because it's local to the function and a new mutex will be created for each time the function is entered.

You need to move the mutex out of the function so it can be shared across calls.
 

That really depends on the resource. As long as it remains immutable to all threads with concurrent access, you'll probably be safe not synchronizing access to it. However you almost always need to rely on documentation to know which operations are thread-safe and which aren't.
 
An std::string in particular doesn't make any guarantees about thread-safety (same situation with most of the standard library*), so you definitely don't want more than one thread accessing it at once, even for ostensibly read-only operations like c_str(). This doesn't necessarily mean that you need to fall-back on locks, but without more information on what you're trying to do, it's hard to suggest better alternative.
 
* There are some implementations that guarantee std::string is thread-safe, but you generally don't want to target specific implementations of the standard library unless you never intend on porting your code to a different platform/compiler/version/etc.


The standard library pretty much guarantees that all accesses through const functions are thread-safe. I.e. as long as you only read data, you don't need to lock.

This is generally recommended for your own code as well, because const functions should never (visibly) affect the state of the object. As such, if you are employing some sort of caching system internal to the object for an expensive calculation, you can make the function const that gets the result, as long as you internally synchronize the checking and creation of the cached value.

Sources/authorities:
StackOverflow discussion on const and thread-safety.

C++ and Beyond 2012 presentation by Herb Sutter: "You don't know _blank_ and _blank_" Edited by SmkViper

Share this post


Link to post
Share on other sites
Zipster    2365


The standard library pretty much guarantees that all accesses through const functions are thread-safe. I.e. as long as you only read data, you don't need to lock.

Thanks for the reference, when I searched yesterday I didn't find anything about it!

Share this post


Link to post
Share on other sites
Bregma    9214


The standard library pretty much guarantees that all accesses through const functions are thread-safe. I.e. as long as you only read data, you don't need to lock.

Do you have a reference to the section of the standard that asserts that?

Share this post


Link to post
Share on other sites
SmkViper    5396

The standard library pretty much guarantees that all accesses through const functions are thread-safe. I.e. as long as you only read data, you don't need to lock.

Do you have a reference to the section of the standard that asserts that?


The StackOverflow answer I linked quotes the relevant sections of the standard and discusses them.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this