5

I am updating some code and I came across several mutexs that were using the lines:

while (!mutex_.try_lock())
    sleep_for(milliseconds(1));

instead of just locking the mutex straight away:

mutex_.lock();

Is there any performance difference positive or negative to using the try lock and sleep approach vs straight locking the mutex or is it just wasted instructions?

user3758015
  • 119
  • 1
  • 9
  • I don't know, but for simple things like this I would expect the library implementation to do these kind of optimizations (better) and I would bet that the first version is actually slower. – znkr Oct 09 '15 at 22:23
  • On average the final `sleep()` will be twice as long as necessary. The shorter you make the sleep interval, the less that matters, but the more CPU cycles you waste. It's pointless. – user207421 Oct 09 '15 at 23:10
  • 1
    It's an attempt at making a spinlock (https://en.wikipedia.org/wiki/Spinlock). `.lock()` calls are generally very fast but quickly slow down when there's contention. If the mutex area is always short, spinlocks are more efficient. – thab Oct 12 '15 at 11:45

1 Answers1

7

lock() will block if the lock is not available, while try_lock() returns straight away even if the lock is not available.

The first form polls the lock until it is available, which has a couple of disadvantages:

  1. Depending on the delay in the loop, there can be unnecessary latency. The lock might become available just after the try_lock attempt, but your process still waits for the preset delay.

  2. It is a waste of CPU cycles polling the lock

In general you should only use try_lock if there is something useful that the thread can do while it is waiting for the lock, in which case you would not want the thread to block waiting for the lock.

Another use case for try_lock would be to attempt locking with a timeout, so that if the lock did not become available within a certain time the program could abort.

cppreference says that:

lock() is usually not called directly: std::unique_lock and std::lock_guard are used to manage exclusive locking.

Using these classes may be more appropriate depending on the circumstances.

harmic
  • 28,606
  • 5
  • 67
  • 91
  • @Macmade It is true that depending on OS facilities available, an implementation could be doing a wait/sleep under the hood. But that's no reason not to use the correct C++ std lib tool for the task at hand – harmic Oct 10 '15 at 00:32