Makefile
cpp
复制代码
cp: testMain.cc
g++ -o cp testMain.cc -std=c++11 -lpthread
.PHONY: clean
clean:
rm -rf cp
ringQueue.hpp
cpp
复制代码
#ifndef RINGQUEUE_HPP
#define RINGQUEUE_HPP
#include <iostream>
#include <vector>
#include <pthread.h>
#include "sem.hpp"
#include <unistd.h>
const int g_default_num = 5;
template <typename T>
class RingQueue
{
public:
RingQueue(int default_num = g_default_num)
: _ring_queue(default_num), _num(default_num), c_step(0), p_step(0), spaceSem(default_num), dataSem(0)
{
pthread_mutex_init(&clock, nullptr);
pthread_mutex_init(&plock, nullptr);
}
void push(const T &in)
{
spaceSem.P();
pthread_mutex_lock(&plock);
_ring_queue[p_step++] = in;
p_step %= _num;
dataSem.V();
pthread_mutex_unlock(&plock);
}
void pop(T *out)
{
dataSem.P();
pthread_mutex_lock(&clock);
*out = _ring_queue[c_step++];
c_step %= _num;
spaceSem.V();
pthread_mutex_unlock(&clock);
}
void debug()
{
std::cerr << "size: " << _ring_queue.size() << " num: " << _num << std::endl;
}
~RingQueue()
{
pthread_mutex_destroy(&clock);
pthread_mutex_destroy(&plock);
}
private:
std::vector<T> _ring_queue;
int _num;
int c_step; // 消费下标
int p_step; // 生产下标
Sem spaceSem; // 空间资源
Sem dataSem; // 数据资源
pthread_mutex_t clock;
pthread_mutex_t plock;
};
#endif
sem.hpp
cpp
复制代码
#ifndef SEM_HPP
#define SEM_HPP
#include <iostream>
#include <semaphore.h>
class Sem
{
public:
Sem(int value)
{
sem_init(&_sem, 0, value);
}
void P()
{
sem_wait(&_sem);
}
void V()
{
sem_post(&_sem);
}
~Sem()
{
sem_destroy(&_sem);
}
private:
sem_t _sem;
};
#endif
cpp
复制代码
#include "ringQueue.hpp"
void *consumer(void *arg)
{
RingQueue<int> *rq = (RingQueue<int> *)arg;
while (true)
{
sleep(1);
int x;
rq->pop(&x);
std::cout << "消费:" << x << "[" << pthread_self() << "]" << std::endl;
}
}
void *productor(void *arg)
{
RingQueue<int> *rq = (RingQueue<int> *)arg;
while (true)
{
int x = rand() % 100 + 1;
rq->push(x);
std::cout << "生产:" << x << "[" << pthread_self() << "]" << std::endl;
}
}
int main()
{
srand((unsigned int)time(nullptr));
pthread_t c[3], p[2];
RingQueue<int> *rq = new RingQueue<int>(4);
rq->debug();
pthread_create(c, nullptr, consumer, (void *)rq);
pthread_create(c + 1, nullptr, consumer, (void *)rq);
pthread_create(c + 2, nullptr, consumer, (void *)rq);
pthread_create(p, nullptr, productor, (void *)rq);
pthread_create(p + 1, nullptr, productor, (void *)rq);
pthread_join(c[0], nullptr);
pthread_join(c[1], nullptr);
pthread_join(c[2], nullptr);
pthread_join(p[0], nullptr);
pthread_join(p[1], nullptr);
}