#include <algorithm>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <queue>
#include <iostream>
#include <string>
using namespace std;
static sem_t my_sem;
static bool done_flag = false;
class DATA
{
public:
DATA(){ size = 0; pthread_mutex_init(&v_mutex, NULL); }
~DATA(){ pthread_mutex_destroy(&v_mutex); }
void add_at_tail(const string &s){ q_string.push(s); }
const string& get_at_head(){ return q_string.front(); }
void del_at_head(){ q_string.pop(); }
bool is_empty(){ return q_string.empty(); }
int get_size(){ return q_string.size(); }
void set_def_size(int n){ size = n; }
int get_def_size(){ return size; }
public:
pthread_mutex_t v_mutex;
private:
queue<string> q_string;
int size;
};
void* product(void *data)
{
DATA *p_data = (DATA*)data;
string q_string;
char str[ 20 ];
int v_int = 0;
do
{
memset(str, '/0', sizeof(str));
sprintf(str, "product %d", v_int++);
q_string = str;
pthread_mutex_lock(&(p_data->v_mutex));
p_data->add_at_tail(q_string);
pthread_mutex_unlock(&(p_data->v_mutex));
if (v_int%10 == 0)
sem_post(&my_sem);
} while (p_data->get_size() <= p_data->get_def_size());
done_flag = true;
sem_post(&my_sem);
cout << endl << "OK!" << endl;
return NULL;
}
void* consume(void *data)
{
DATA *p_data = (DATA*)data;
int sem_value = 0;
do
{
if (sem_wait(&my_sem))
{
break;
}
sem_getvalue(&my_sem, &sem_value);
if ((done_flag == true) && (sem_value <= 0))
break;
pthread_mutex_lock(&(p_data->v_mutex));
cout << "consume " << p_data->get_at_head() << endl;
p_data->del_at_head();
pthread_mutex_unlock(&(p_data->v_mutex));
} while(p_data->is_empty() == false);
return NULL;
}
int main(void)
{
DATA data;
int v_pthread_product_id[2];
int v_pthread_consume_id;
pthread_t v_pthread_product[2];
pthread_t v_pthread_consume;
sem_init(&my_sem, 0, 0);
for (int i = 0; i < 2; i++)
{
data.set_def_size((i+1)*10000);
v_pthread_product_id[i] = pthread_create(&v_pthread_product[i], NULL, product, (void*)&data);
}
// sleep(2);
v_pthread_consume_id = pthread_create(&v_pthread_consume, NULL, consume, (void*)&data);
for (int j = 0; j < 2; j++)
{
pthread_join(v_pthread_product[j], NULL);
}
pthread_join(v_pthread_consume, NULL);
sem_destroy(&my_sem);
return 0;
}