访客地图

pthread线程通信方式之pthread_mutex_t与pthread_cond_t条件等待二者配合使用

张成
2016/6

#include <iostream>
using namespace std;
/**
 * pthread 同步 - 锁
 */
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#define BUFFER_SIZE 4
#define OVER (-1)
struct producers
{
    int buffer[BUFFER_SIZE];
    pthread_mutex_t lock;
    int readpos, writepos;
    pthread_cond_t notempty;
    pthread_cond_t notfull;
};
/**
 * init
 */
void init(struct producers *b)
{
    pthread_mutex_init(&b->lock, nullptr);
    pthread_cond_init(&b->notempty, nullptr);
    pthread_cond_init(&b->notfull, nullptr);
    b->readpos = 0;
    b->writepos = 0;
}
void put(struct producers* b,int data)
{
    pthread_mutex_lock(&b->lock);
    while((b->writepos+1)%BUFFER_SIZE == b->readpos) //写满了 不能在写了
    {
        //等待被激发
        printf("put wait -buffer data is now full  ,waiting for data not full--\n");
        pthread_cond_wait(&b->notfull,&b->lock);// 等待的时候 会自动释放锁 被激活时 会自动加锁
    }
    //写入一个字
    b->buffer[b->writepos] = data;
    b->writepos++;
    if(b->writepos>=BUFFER_SIZE) // //下个写入位置
        b->writepos = 0;
    pthread_cond_signal(&b->notempty);//激发条件
    pthread_mutex_unlock(&b->lock);
}
int get(struct producers* b)
{
    int data;
    pthread_mutex_lock(&b->lock);
    printf("Get lock");
    while(b->writepos == b->readpos) //未写入 或者 已读完
    {
        pthread_cond_wait(&b->notempty,&b->lock);
    }
    data = b->buffer[b->readpos];
    b->readpos++;
    if(b->readpos>= BUFFER_SIZE)
        b->readpos = 0;
    pthread_cond_signal(&b->notfull);//激发notfull 已经消费一定的buffer data了  激发producer继续生产
    pthread_mutex_unlock(&b->lock);
    return data;
}
struct producers buffer;
void* producer(void* data)
{
    int n;
    for(n=0;n<10;n++)
    {
        printf("Producer: %d --> \n",n);
        put(&buffer,n); //打印buffer中的数据
    }
    put(&buffer,OVER);
    return nullptr;
}
void* consumer(void* data)
{
    int d;
    while(1)
    {
        d=get(&buffer);
        if(d==OVER)
            break;
        printf("Consumer 1: --> %d\n",d);
    }
    return nullptr;
}
int main() {
    cout << "Hello, World!" << endl;
    pthread_t tha, thb, thc;
    void* retval;
    init(&buffer);
    pthread_create(&tha, nullptr,producer,0);
    pthread_create(&thb,nullptr,consumer,0);
    pthread_join(tha,&retval);
    pthread_join(thb,&retval);
    cout<<"hello end"<<endl;
    return 0;
}