Reputation: 17253
I am reading about Semaphores. From what I understand is that a Semaphore allows only a certain number of threads to access a specific resource. I came across this post which explains how to create a simple semaphore class using condition variables and a mutex. The code for ease of access is pasted here from that link
#include <mutex>
#include <condition_variable>
class Semaphore {
public:
Semaphore (int count_ = 0)
: count(count) {}
inline void notify()
{
std::unique_lock<std::mutex> lock(mtx);
count++;
cv.notify_one();
}
inline void wait()
{
std::unique_lock<std::mutex> lock(mtx);
while(count == 0){
cv.wait(lock);
}
count--;
}
private:
std::mutex mtx;
std::condition_variable cv;
int count;
};
My question is how would I use the above class to make this method accessible to only 3 threads at a time
void SomeFunction
{
------------------------------> Only 3 threads should be allowed access to this function concurrently
int a = getSomeValue();
//Do something useful
------------------------------>
}
I am thinking that I would do something like this
Semaphore s(3);
void SomeFunction
{
s.wait();
int a = getSomeValue();
//Do sometning useful
s.notify();
}
However I am not sure when wait()
and notify()
would be called ?
Upvotes: 1
Views: 724
Reputation: 15100
It would be better to use RAII idiom for a semaphore:
class SemaphoreLock
{
public:
SemaphoreLock(Semaphore& s)
: _pS(&s)
{
_pS->wait();
}
~SemaphoreLock()
{
_pS->notify();
}
private:
Semaphore* _pS;
};
Semaphore s(3);
void SomeFunction()
{
SemaphoreLock sl(s);
// implement the function here
}
If SemaphoreLock
object is declared in the very beginning of the body of the function, then wait()
would be called upon entering the function and notify()
would be called just before exiting the function, also in the case if an exception is thrown and stack unwinding is not terminated.
An even better solution could be in renaming the methods of Semaphore: wait
into lock
and notify
into unlock
. In this case one would be able to use std::lock_guard<Semaphore>
in place of self-written SemaphoreLock
class.
Upvotes: 2