-2

What can you use for locking in C++ besides mutex? Is there anything at the processor level which can be used?

SilverBackApe
  • 227
  • 4
  • 15
  • 2
    What do you mean by "for locking"? – David Schwartz Oct 01 '14 at 03:46
  • There are "lock free" methods of protecting shared resources. – imreal Oct 01 '14 at 03:50
  • See [Test-and-set on Wikipedia](http://en.wikipedia.org/wiki/Test-and-set). – kmac Oct 01 '14 at 03:54
  • You need to provide a bit more information about what kind of "locking" you're talking about. For example, there *is* a processor-level `LOCK`, but its use is pretty limited. See http://stackoverflow.com/questions/8891067/what-does-the-lock-instruction-mean-in-x86-assembly – Jim Mischel Oct 01 '14 at 03:54

3 Answers3

1

You can use a compare and swap, similar to this:

std::atomic_bool locked = false;
bool f = false;
... // spawn threads n' stuff
do {
  bool got_lock = atomic_compare_exchange_weak(locked, &f, true);
  if (got_lock) {
     ... // do stuff
     locked = false;
  }
}
while(!got_lock)

I named the variables locked and got_lock conceptually, but there's no real locking going on here. The function atomic_compare_exchange_weak takes advantage of a special assembly instruction to be atomic.

To understand how it works: it enters the do while loop and immediately tries the CAS. The CAS compares the value of locked to the value contained at f, which is false. If and only if they compare equal, it sets locked to the third argument (true) and returns true. Otherwise, this means that another thread already set locked to true, so it returns false and does not change the value of locked. We can see that if a thread gets the lock, it enters the if, does some stuff, and then releases the lock. If it does not get the lock, it does not go through the if, but it does get bounced back up by the while loop. It continues in this very fast while loop until the CAS call succeeds.

So, where I have written the comment "do stuff", you are guaranteed that only one thread can be at once.

Nir Friedman
  • 17,108
  • 2
  • 44
  • 72
0

If you developing under Operating System then you can also use Semaphores. In comparison to mutexes semaphore can be initialized with a certain number as a counter. The value you initizize semaphore with allows any caller to get resource or execute a critical code section until the value(the semaphore) is greater than zero. When it downcounts to zero any new caller will be waiting for freeing/releasing a semaphore. And the binary semaphores are mutexes themselves.

Ruslan Gerasimov
  • 1,752
  • 1
  • 13
  • 20
0

The operating system primitives have a key advantage over a lock, in that using the OS primitives will put your thread into the wait queue in the kernel. When a mutex is released, your thread can be woken up automatically by the OS and kicked off. If you use a compare/exchange type check, you are responsible for writing your spinlock and sleeping appropriately (otherwise when you don't have the lock, you'll be using 100% of the processor (or core) waiting for it to be freed).

Mutex excels in cross process synchronisation (which requires the operating system). Semaphore is very similar, except that it allows concurrent access to a critical section (for example permitting 4 threads to run only from a work queue to optimise work on a multi core processor).

You also have "CRITICAL_SECTION" MSDN LINK which can be utilised if you are only synchronising threads in the same process. This will be faster as you don't need a syscall to implement the lock.

Spence
  • 28,526
  • 15
  • 68
  • 103