在 Linux 下,C++ 可以使用 POSIX 信号量(semaphore)来进行线程或进程间的同步。POSIX 信号量有两种类型:命名信号量和未命名信号量。这里我们主要讨论未命名信号量的使用。
要在 C++ 中使用信号量进行同步,请按照以下步骤操作:
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>
#include <iostream>
#include <pthread.h>
sem_t semaphore;
// 初始化信号量
int sem_init(sem_t *sem, int pshared, unsigned int value) {
return sem_init(sem, pshared, value);
}
// 等待信号量
int sem_wait(sem_t *sem) {
return sem_wait(sem);
}
// 释放信号量
int sem_post(sem_t *sem) {
return sem_post(sem);
}
int sem_destroy(sem_t *sem) {
return sem_destroy(sem);
}
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>
#include <iostream>
#include <pthread.h>
sem_t empty; // 表示空槽位的信号量
sem_t full; // 表示满槽位的信号量
int buffer[10]; // 缓冲区
int in = 0; // 生产者插入位置
int out = 0; // 消费者取出位置
void* producer(void* arg) {
for (int i = 0; i < 20; ++i) {
sem_wait(&empty); // 等待空槽位
buffer[in] = i;
in = (in + 1) % 10;
std::cout << "Produced: "<< i << std::endl;
sem_post(&full); // 增加满槽位
}
return nullptr;
}
void* consumer(void* arg) {
for (int i = 0; i < 20; ++i) {
sem_wait(&full); // 等待满槽位
int item = buffer[out];
out = (out + 1) % 10;
std::cout << "Consumed: " << item << std::endl;
sem_post(&empty); // 增加空槽位
}
return nullptr;
}
int main() {
pthread_t producer_thread, consumer_thread;
sem_init(&empty, 0, 10); // 初始化空槽位信号量为10
sem_init(&full, 0, 0); // 初始化满槽位信号量为0
pthread_create(&producer_thread, nullptr, producer, nullptr);
pthread_create(&consumer_thread, nullptr, consumer, nullptr);
pthread_join(producer_thread, nullptr);
pthread_join(consumer_thread, nullptr);
sem_destroy(&empty);
sem_destroy(&full);
return 0;
}
编译并运行示例:
g++ -o semaphore_example semaphore_example.cpp -pthread
./semaphore_example
这个示例中,我们使用两个信号量(empty 和 full)来同步生产者和消费者线程。生产者线程在生产数据之前等待空槽位,消费者线程在消费数据之前等待满槽位。这样可以确保生产者和消费者线程之间的同步。