linux 下 条件变量实现生产者消费者问题
/*
* file4.cpp
*
* Created on: 2010-8-2
* Author: zollyzhu
*/
#include "Head.h"
#define BUFFER_SIZE 2
class CProductor {
private:
int m_sBufer[BUFFER_SIZE];
int m_iReadPos;
int m_iWritePos;
pthread_cond_t m_pNotEmpty;
pthread_cond_t m_pNotFull;
pthread_mutex_t m_pMutex;
public:
CProductor() {
m_iReadPos = 0;
m_iWritePos = 0;
pthread_cond_init(&m_pNotEmpty,NULL);
pthread_cond_init(&m_pNotFull,NULL);
pthread_mutex_init(&m_pMutex,NULL);
}
~CProductor() {
pthread_cond_destroy(&m_pNotEmpty);
pthread_cond_destroy(&m_pNotFull);
pthread_mutex_destroy(&m_pMutex);
}
void Put(int data) {
pthread_mutex_lock(&m_pMutex);
if ((m_iWritePos + 1) % BUFFER_SIZE == m_iReadPos) {
cout << "Producer wait for not full" << endl;
pthread_cond_wait(&m_pNotFull, &m_pMutex);
}
m_sBufer[m_iWritePos] = data;
m_iWritePos++;
if (m_iWritePos >= BUFFER_SIZE) {
m_iWritePos = 0;
}
pthread_cond_signal(&m_pNotEmpty);
pthread_mutex_unlock(&m_pMutex);
}
int Get() {
int data;
pthread_mutex_lock(&m_pMutex);
if (m_iWritePos == m_iReadPos) {
cout << "Read wait for not empty" << endl;
pthread_cond_wait(&m_pNotEmpty, &m_pMutex);
}
data = m_sBufer[m_iReadPos];
m_iReadPos++;
if (m_iReadPos >= BUFFER_SIZE) {
m_iReadPos = 0;
}
pthread_cond_signal(&m_pNotFull);
pthread_mutex_unlock(&m_pMutex);
return data;
}
};
CProductor productor;
void * produce(void * data)
{
int i = 1;
for(; i <= 5; i++)
{
cout<<"producer sleep 1"<<endl;
sleep(1);
cout<<"producer put "<<i<<" to the buffer"<<endl;
productor.Put(i);
}
for(i = 6; i <= 10; i++)
{
cout<<"producer sleep 2"<<endl;
sleep(3);
cout<<"producer put "<<i<<" to the buffer"<<endl;
productor.Put(i);
}
productor.Put(-1);
cout<<"over"<<endl;
return (char *)0;
}
void * consumer(void * data)
{
int d;
while(1)
{
cout<<"consumer sleep 2"<<endl;
sleep(2);
d = productor.Get();
cout<<"get data "<<d<<endl;
if(d == -1)
break;
}
cout<<"consumer over"<<endl;
return (char *)0;
}
int main()
{
pthread_t a, b;
pthread_create(&a, NULL, produce, 0);
pthread_create(&b, NULL, consumer, 0);
pthread_join(a,NULL);
pthread_join(b,NULL);
return 0;
}
* file4.cpp
*
* Created on: 2010-8-2
* Author: zollyzhu
*/
#include "Head.h"
#define BUFFER_SIZE 2
class CProductor {
private:
int m_sBufer[BUFFER_SIZE];
int m_iReadPos;
int m_iWritePos;
pthread_cond_t m_pNotEmpty;
pthread_cond_t m_pNotFull;
pthread_mutex_t m_pMutex;
public:
CProductor() {
m_iReadPos = 0;
m_iWritePos = 0;
pthread_cond_init(&m_pNotEmpty,NULL);
pthread_cond_init(&m_pNotFull,NULL);
pthread_mutex_init(&m_pMutex,NULL);
}
~CProductor() {
pthread_cond_destroy(&m_pNotEmpty);
pthread_cond_destroy(&m_pNotFull);
pthread_mutex_destroy(&m_pMutex);
}
void Put(int data) {
pthread_mutex_lock(&m_pMutex);
if ((m_iWritePos + 1) % BUFFER_SIZE == m_iReadPos) {
cout << "Producer wait for not full" << endl;
pthread_cond_wait(&m_pNotFull, &m_pMutex);
}
m_sBufer[m_iWritePos] = data;
m_iWritePos++;
if (m_iWritePos >= BUFFER_SIZE) {
m_iWritePos = 0;
}
pthread_cond_signal(&m_pNotEmpty);
pthread_mutex_unlock(&m_pMutex);
}
int Get() {
int data;
pthread_mutex_lock(&m_pMutex);
if (m_iWritePos == m_iReadPos) {
cout << "Read wait for not empty" << endl;
pthread_cond_wait(&m_pNotEmpty, &m_pMutex);
}
data = m_sBufer[m_iReadPos];
m_iReadPos++;
if (m_iReadPos >= BUFFER_SIZE) {
m_iReadPos = 0;
}
pthread_cond_signal(&m_pNotFull);
pthread_mutex_unlock(&m_pMutex);
return data;
}
};
CProductor productor;
void * produce(void * data)
{
int i = 1;
for(; i <= 5; i++)
{
cout<<"producer sleep 1"<<endl;
sleep(1);
cout<<"producer put "<<i<<" to the buffer"<<endl;
productor.Put(i);
}
for(i = 6; i <= 10; i++)
{
cout<<"producer sleep 2"<<endl;
sleep(3);
cout<<"producer put "<<i<<" to the buffer"<<endl;
productor.Put(i);
}
productor.Put(-1);
cout<<"over"<<endl;
return (char *)0;
}
void * consumer(void * data)
{
int d;
while(1)
{
cout<<"consumer sleep 2"<<endl;
sleep(2);
d = productor.Get();
cout<<"get data "<<d<<endl;
if(d == -1)
break;
}
cout<<"consumer over"<<endl;
return (char *)0;
}
int main()
{
pthread_t a, b;
pthread_create(&a, NULL, produce, 0);
pthread_create(&b, NULL, consumer, 0);
pthread_join(a,NULL);
pthread_join(b,NULL);
return 0;
}