将临界资源分成多份,支持多线程并发同步。互斥锁能保护临界资源,条件变量能帮我们直到临界资源的状态。信号量是一种资源的预定机制。线程来了,获取信号量,有资源就进去执行,执行完毕,让出资源;获取信号量时没有资源,则挂起等待。信号量本身也是一种临界资源,所以其P(申请资源)V(释放资源操作)操作是原子性的。
sem_t
int sem_init(sem_t *sem, int pshared, unsigned int value);
value
:信号量初始值,多少份临界资源。int sem_destroy(sem_t *sem);
int sem_wait(sem_t *sem);
sem--
;大于0,立即返回;反之则阻塞等待。int sem_post(sem_t *sem);
sem++
。---//hpp
#pragma once
#include
#include
#include
#include
template <class T>
class RingQueue{
private:
int cap;
std::vector<T> ring;
//生产和消费必须有自己的位置下标
int c_index;
int p_index;
pthread_mutex_t c_lock;//多个消费线程
pthread_mutex_t p_lock;//多个生产线程 都要保证互斥
sem_t sem_space;
sem_t sem_data;
public:
RingQueue(int _cap):cap(_cap), ring(_cap), c_index(0), p_index(0)
{
pthread_mutex_init(&c_lock, nullptr);
pthread_mutex_init(&p_lock, nullptr);
sem_init(&sem_space, 0, _cap);
sem_init(&sem_data, 0, 0);
}
void Put(const T &in)
{
sem_wait(&sem_space);
//lock //生产者
ring[p_index] = in;
sem_post(&sem_data);
p_index++;
p_index %= cap;
//unlock
}
void Get(T *out)
{
sem_wait(&sem_data);
//lock 消费者
*out = ring[c_index];
sem_post(&sem_space);
c_index++;
c_index %= cap;
//unlock
}
~RingQueue()
{
pthread_mutex_destroy(&c_lock);
pthread_mutex_destroy(&p_lock);
sem_destroy(&sem_space);
sem_destroy(&sem_data);
}
};
---//main.cc
#include "RingQueue.hpp"
#include "Task.hpp"
#include
#include
#include
#include
void *consumer(void *ring_queue)
{
RingQueue<Task> *rq = (RingQueue<Task>*)ring_queue;
while(true){
//sleep(1);
//1. 消费任务
Task t;
rq->Get(&t);
//2. 处理任务
int result = t.Handler();
std::cout << "消费者: hander Task Done , result: " << result << std::endl;
}
}
void *producter(void *ring_queue)
{
RingQueue<Task> *rq = (RingQueue<Task>*)ring_queue;
while(true){
//1. 制造任务, 或者别人给你的
int top = rand()%20000+1; //[1, 2000]
Task t(top);
t.Show();
//2. 生产任务
rq->Put(t);
}
}
int main()
{
RingQueue<Task> *rq = new RingQueue<Task>(10);
pthread_t c, p;
pthread_create(&c, nullptr, consumer, rq);
pthread_create(&p, nullptr, producter, rq);
pthread_join(c, nullptr);
pthread_join(p, nullptr);
return 0;
}
---//任务.hpp
#include
class Task{
private:
int top; //[1,top]
public:
Task()
:top(1)
{}
Task(int _top)
:top(_top)
{}
int Handler()
{
int sum = 0;
for(auto i= 0; i <= top; i++){
sum += i;
}
return sum;
}
void Show()
{
std::cout << "生产者:这个任务是:累加数据从1~" << top << std::endl;
}
~Task()
{}
};