如何使用以下信号量代码
How to use the following Semaphore code
我正在阅读有关信号量的内容。据我了解,信号量只允许一定数量的线程访问特定资源。我遇到了这个 post,它解释了如何使用条件变量和互斥锁创建一个简单的信号量 class。为了便于访问,这里粘贴了 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;
};
我的问题是如何使用上面的 class 让这个方法一次只能被 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()
将在退出之前被调用该函数,在抛出异常且堆栈展开未终止的情况下也是如此。
一个更好的解决方案可能是将 Semaphore 的方法重命名:wait
重命名为 lock
和 notify
重命名为 unlock
。在这种情况下,可以使用 std::lock_guard<Semaphore>
代替自己编写的 SemaphoreLock
class.
我正在阅读有关信号量的内容。据我了解,信号量只允许一定数量的线程访问特定资源。我遇到了这个 post,它解释了如何使用条件变量和互斥锁创建一个简单的信号量 class。为了便于访问,这里粘贴了 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;
};
我的问题是如何使用上面的 class 让这个方法一次只能被 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()
将在退出之前被调用该函数,在抛出异常且堆栈展开未终止的情况下也是如此。
一个更好的解决方案可能是将 Semaphore 的方法重命名:wait
重命名为 lock
和 notify
重命名为 unlock
。在这种情况下,可以使用 std::lock_guard<Semaphore>
代替自己编写的 SemaphoreLock
class.