55.C++线程控制_信号量
约 428 字大约 1 分钟
计数信号量 std::counting_semaphore
#include <iostream>
#include <thread>
#include <semaphore> // C++20
std::counting_semaphore<3> sem(3); // 计数信号量,最多允许 3 个线程访问
void worker(int id) {
sem.acquire(); // 获取信号量
std::cout << "线程 " << id << " 进入临界区\n";
std::this_thread::sleep_for(std::chrono::seconds(1)); // 模拟工作
std::cout << "线程 " << id << " 退出临界区\n";
sem.release(); // 释放信号量
}
int main() {
std::thread threads[5];
for (int i = 0; i < 5; ++i)
threads[i] = std::thread(worker, i + 1);
for (auto& t : threads)
t.join();
return 0;
}
二进制信号量 std::binary_semaphore
#include <iostream>
#include <thread>
#include <semaphore> // C++20
std::binary_semaphore semA(1); // 初始允许线程 A 运行
std::binary_semaphore semB(0); // 线程 B 需要等待
void threadA() {
for (int i = 0; i < 5; ++i) {
semA.acquire(); // 等待信号
std::cout << "A" << std::endl;
semB.release(); // 通知线程 B
}
}
void threadB() {
for (int i = 0; i < 5; ++i) {
semB.acquire(); // 等待线程 A
std::cout << "B" << std::endl;
semA.release(); // 通知线程 A
}
}
int main() {
std::thread t1(threadA);
std::thread t2(threadB);
t1.join();
t2.join();
return 0;
}
经典生产者-消费者模型
#include <iostream>
#include <thread>
#include <semaphore>
#include <queue>
#include <chrono>
std::counting_semaphore<1> empty_slots(1); // 1 个空槽位(生产者等待)
std::counting_semaphore<0> filled_slots(0); // 0 个数据(消费者等待)
std::mutex mtx; // 保护共享队列
std::queue<int> buffer; // 共享缓冲区
void producer() {
for (int i = 1; i <= 5; ++i) {
empty_slots.acquire(); // 等待空槽
{
std::lock_guard<std::mutex> lock(mtx);
buffer.push(i);
std::cout << "生产者:生产数据 " << i << std::endl;
}
filled_slots.release(); // 通知消费者
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
}
void consumer() {
for (int i = 1; i <= 5; ++i) {
filled_slots.acquire(); // 等待数据
{
std::lock_guard<std::mutex> lock(mtx);
int value = buffer.front();
buffer.pop();
std::cout << "消费者:消费数据 " << value << std::endl;
}
empty_slots.release(); // 通知生产者
std::this_thread::sleep_for(std::chrono::milliseconds(800));
}
}
int main() {
std::thread t1(producer);
std::thread t2(consumer);
t1.join();
t2.join();
return 0;
}