需求:
- 支持push:缓冲区满了应当阻塞等待
- 支持pop:移除缓冲区元素
- 支持size:获取缓冲区大小
- 支持多个生产者和消费者同时访问,并保证线程安全
#include <queue>
#include <conditonal_variable>
#include <thread>
#include <mutex>
template <typename T>
class SaveBufer {
private:
std::queue<T> m_queue;
std::conditonal_variable consumer_con;
std::conditonal_variable producer_con;
int m_size;
std::mutex m_mux; // !
public:
explict SaveBufer(int size) {
m_size = size;
}
void push(T &item);
T& pop();
int size(){
std::lock_guard<std::mutex> lock(m_mux);//!!
return m_queue.size();
}
};
template <typename T>
void SaveBufer<T>::push(T& item)//!
{
std::unique_lock<std::mutex> lock(m_mux);//!!
producer_con.wait(lock,[this](){
return m_queue.size() < m_size;
});
m_queue.push(item);
consumer_con.notify_all();//!!
}
template <typename T>
T& SaveBufer<T>::pop()
{
std::unique_lock<std::mutex> lock(m_mux);//!!
consumer_con.wait(lock,[this](){
return m_queue.size() > 0;
});
T& item = m_queue.front();
m_queue.pop();
producer_con.notify_all();
return item;
}
void consumer(int id,std::shared_ptr<SaveBufer<int>> buf)//!
{
while(true) {
buf.pop();
std::cout << "id:" << id << ",consume\n";
std::this_thread::sleep_for(std::chrono::second(1));
}
}
void produce(int id,std::shared_ptr<SaveBufer<int>> buf)
{
while(true) {
int a = 100;
buf.push(a);
std::cout << "id:" << id << ",produce\n";
std::this_thread::sleep_for(std::chrono::second(1));
}
}
int main()
{
std::shared_ptr<SaveBuffer<int>> buf = std::make_shared<SaveBuffer<int>>(10);
std::thread t1(consumer,1,std::ref(buf));//用ref!!
std::thread t2(produce,2,std::ref(buf));
t1.join();
t2.join();
}