进程同步实验,用c++模拟几个进程的执行过程,并使用信号量解决生产者和消费者问题
时间: 2023-12-14 21:39:25 浏览: 81
好的,进程同步是操作系统中非常重要的一个话题,其中信号量是一种重要的同步机制。下面是一个用C++模拟生产者和消费者问题的程序,并使用信号量解决。
```
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
using namespace std;
const int kItemNum = 10; // 缓冲区大小
queue<int> buffer; // 缓冲区
mutex buffer_mutex; // 缓冲区互斥锁
condition_variable buffer_not_full_cv; // 缓冲区未满条件变量
condition_variable buffer_not_empty_cv; // 缓冲区非空条件变量
class Semaphore {
public:
Semaphore(int count = 0) : count_(count) {}
void Signal() {
unique_lock<mutex> lock(mutex_);
++count_;
cv_.notify_one();
}
void Wait() {
unique_lock<mutex> lock(mutex_);
while (count_ == 0) {
cv_.wait(lock);
}
--count_;
}
private:
mutex mutex_;
condition_variable cv_;
int count_;
};
Semaphore buffer_sem(0); // 缓冲区信号量
Semaphore empty_sem(kItemNum); // 空槽位信号量
Semaphore full_sem(0); // 满槽位信号量
void producer(int id) {
for (int i = 0; i < 20; ++i) {
empty_sem.Wait(); // 等待一个空槽位
buffer_mutex.lock(); // 加锁
int item = rand() % 100 + 1;
buffer.push(item);
cout << "Producer " << id << " produce item " << item << endl;
buffer_mutex.unlock(); // 解锁
buffer_not_empty_cv.notify_all(); // 唤醒消费者
full_sem.Signal(); // 增加一个满槽位
}
}
void consumer(int id) {
for (int i = 0; i < 20; ++i) {
full_sem.Wait(); // 等待一个满槽位
buffer_mutex.lock(); // 加锁
int item = buffer.front();
buffer.pop();
cout << "Consumer " << id << " consume item " << item << endl;
buffer_mutex.unlock(); // 解锁
buffer_not_full_cv.notify_all(); // 唤醒生产者
empty_sem.Signal(); // 增加一个空槽位
}
}
int main() {
srand(time(nullptr));
vector<thread> producers;
vector<thread> consumers;
for (int i = 0; i < 3; ++i) {
producers.emplace_back(producer, i);
}
for (int i = 0; i < 3; ++i) {
consumers.emplace_back(consumer, i);
}
for (auto& t : producers) {
t.join();
}
for (auto& t : consumers) {
t.join();
}
return 0;
}
```
在这个程序中,我们定义了三个生产者和三个消费者线程。生产者线程随机生成一个数字并将其放入缓冲区,消费者线程从缓冲区中取出一个数字并输出。为了保证生产者和消费者不会同时访问缓冲区,我们使用了信号量来进行同步。其中,缓冲区信号量表示缓冲区中有多少个项目,空槽位信号量表示缓冲区中还有多少个空槽位,满槽位信号量表示缓冲区中还有多少个满槽位。在生产者线程中,当缓冲区没有满的槽位时,生产者需要等待一个空槽位信号量,然后加锁访问缓冲区,向缓冲区中添加一个项目,增加缓冲区信号量,并唤醒消费者线程。在消费者线程中,当缓冲区中没有满槽位时,消费者需要等待一个满槽位信号量,然后加锁访问缓冲区,从缓冲区中取出一个项目,减少缓冲区信号量,并唤醒生产者线程。这样就实现了生产者和消费者的同步。
需要注意的是,在访问缓冲区时需要使用互斥锁来保证线程安全。同时,我们还使用了条件变量来进行线程的阻塞和唤醒,以避免线程的空轮询。
阅读全文