Reputation: 11890
Here is an implementation of Spinlock class using STL atomic_flag, Taken from https://www.modernescpp.com/index.php/the-atomic-flag.
class Spinlock{
public:
Spinlock(): flag(ATOMIC_FLAG_INIT) {}
void lock(){
while( flag.test_and_set() );
}
void unlock(){
flag.clear();
}
private:
std::atomic_flag flag;
};
And I can use it for any critical section of the code:
void myfunction() {
std::lock_guard<Spinlock> guard(_spinLock);
...
}
Revised question:
For critical sections, seems I now have two choices - std::mutex and std::atomic_flag. When does it make sense to use one over the other?
Upvotes: 0
Views: 2418
Reputation: 623
The question is: what do you want to achieve and what sacrifices are you willing to make for that?
std::atomic_flag is constantly asking for the lock to get access to the critical section, which keeps the CPU core on which it is running 100% busy. It won't be a problem if you have enough cores you can operate with, or not many of your threads are operating on the same critical section at the same time. It saves an expensive context switch though between user space and kernel space.
std::mutex on the other hand will not keep its core busy. You can't observe a significant load on any of the cores with this solution. That's because the thread gets suspended by the scheduler while other threads do some work. It means that the state of the thread gets stored and then restored and resumed later.
Upvotes: 4
Reputation: 76297
std::mutex
can be used also in conjunction with conditions, which your class cannot directly do. It also works nicely with scoped locks.
Asides from that, your statement
it is more efficient
is not categorically true. The line
while( flag.test_and_set() );
is busy waiting, which in some settings is efficient, and in other settings inferior to exponential backoff, for example.
Upvotes: 4