task.hpp(用来封装一个任务):
#include <iostream>
#include <mutex>
#include <queue>
#include <unistd.h>
#include <pthread.h>
using namespace std;
class Task
{
public:
Task()
{
pthread_mutex_init(&_mtx, nullptr);
pthread_cond_init(&_empty, nullptr);
pthread_cond_init(&_full, nullptr);
}
void Push(int x)
{
pthread_mutex_lock(&_mtx);
while(_q.size() >= 6)
{
pthread_cond_signal(&_empty);
pthread_cond_wait(&_full,&_mtx);
}
cout<<"生产了:"<<x<<endl;
_q.push(x);
pthread_mutex_unlock(&_mtx);
}
void Pop()
{
pthread_mutex_lock(&_mtx);
pthread_cond_wait(&_empty, &_mtx);
std::cout << "弹出了一个元素:" << _q.front() << std::endl;
_q.pop();
if(_q.size()==0) pthread_cond_signal(&_full);
pthread_mutex_unlock(&_mtx);
}
private:
pthread_mutex_t _mtx;
pthread_cond_t _empty;
pthread_cond_t _full;
std::queue<int> _q;
};
注意: 用while(_q.empty()) 而不用if(_q.empty()) 的原因是条件变量的实现可能依赖于操作系统或线程库的具体实现,而这些实现可能会导致虚假唤醒。例如,在某些情况下,操作系统可能会在没有通知的情况下唤醒线程,以提高性能或实现其他功能。
.cc文件:
#include"task.hpp"
void* consumer(void* args)
{
Task* t = (Task*)args;
while(1)
{
sleep(1);
t->Pop();
}
return nullptr;
}
void* producer(void* args)
{
Task* t = (Task*)args;
while(1)
{
sleep(1);
t->Push(rand()%1000);
}
return nullptr;
}
int main()
{
srand(time(nullptr));
Task* t = new Task;
pthread_t Consumer[5];
pthread_t Producer[5];
for(int i = 0; i < 5; i++)
{
pthread_create(&Consumer[i], nullptr, consumer, (void*)t);
pthread_create(&Producer[i], nullptr, producer, (void*)t);
}
for(int i = 0; i < 5; i++)
{
pthread_join(Consumer[i], nullptr);
pthread_join(Producer[i], nullptr);
}
delete t;
return 0;
}