我正在阅读有关信号量的内容。据我了解,信号量只允许一定数量的线程访问特定资源。我遇到了这个 post它解释了如何使用条件变量和互斥锁创建一个简单的信号量类。方便访问的代码从该链接粘贴到此处
#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;
};
我的问题是如何使用上面的类来使这个方法一次只能被 3 个线程访问
void SomeFunction
{
------------------------------> Only 3 threads should be allowed access to this function concurrently
int a = getSomeValue();
//Do something useful
------------------------------>
}
我想我会做这样的事情
Semaphore s(3);
void SomeFunction
{
s.wait();
int a = getSomeValue();
//Do sometning useful
s.notify();
}
但是我不确定何时会调用 wait()
和 notify()
?
最佳答案
最好用RAII idiom对于信号量:
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
}
如果SemaphoreLock
对象在函数体的最开始声明,然后是wait()
将在进入函数时被调用,notify()
将在退出函数之前调用,如果抛出异常且堆栈展开未终止,也是如此。
更好的解决方案可能是重命名信号量的方法:wait
进入lock
和 notify
进入unlock
.在这种情况下,可以使用 std::lock_guard<Semaphore>
代替自写SemaphoreLock
类。
关于c++ - 如何使用以下信号量代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31190252/