#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
class Semaphore {
public:
Semaphore(int count = 0) : count_(count) {}
// 等待信号量,如果信号量计数器大于0则直接返回;否则阻塞线程等待
void wait() {
std::unique_lock<std::mutex> lock(mutex_); // 使用unique_lock进行加锁
cv_.wait(lock, [this] { return count_ > 0; }); // 等待条件变量满足,即信号量计数器大于0
--count_; // 获取到信号量后将计数器减1
}
// 发送信号量,将信号量计数器加1,并通知等待的线程
void signal() {
std::lock_guard<std::mutex> lock(mutex_); // 使用lock_guard进行加锁
++count_; // 释放信号量,将计数器加1
cv_.notify_one(); // 通知等待线程中的一个线程可以继续执行了
}
private:
std::mutex mutex_; // 互斥锁,用于保护信号量计数器的访问
std::condition_variable cv_; // 条件变量,用于线程间的同步和通信
int count_; // 信号量计数器,表示当前可用的资源数
};
int main() {
Semaphore sem(1); // 初始化一个信号量,表示当前可用的资源数为1
int count = 0; // 计数器,用于记录获取资源的次数
// 创建两个线程,同时访问资源
std::thread t1([&] {
sem.wait(); // 等待信号量,获取到信号量后继续执行
++count; // 计数器加1
sem.signal(); // 发送信号量,释放资源
});
std::thread t2([&] {
sem.wait(); // 等待信号量,获取到信号量后继续执行
++count; // 计数器加1
sem.signal(); // 发送信号量,释放资源
});
t1.join(); // 等待线程1执行完毕
t2.join(); // 等待线程2执行完毕
std::cout << "count = " << count << std::endl; // 输出获取资源的次数
return 0;
}