linux Posix线程同步(条件变量) 实例

来源:互联网 发布:淘宝上怎么买微信号 编辑:程序博客网 时间:2024/05/19 03:43

条件变量:与互斥量一起使用,暂时申请不到某资源时进入条件阻塞等待,当资源具备时线程恢复运行
应用场合:生产线程不断的生产资源,并通知产生资源的条件,消费线程在没有资源情况下进入条件等待,一直等到条件信号的产生
主要函数有两个:
1)等待条件
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
2)发送条件信号
int pthread_cond_signal(pthread_cond_t *cond);


请参考:

http://www.diybl.com/course/3_program/c++/cppjs/20110518/555794.html

http://www.ibm.com/developerworks/cn/linux/thread/posix_threadapi/part3/


编译:

gcc -o pthread pthread.c -lpthread


/*单个生产者和单个消费者*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <unistd.h>#include <pthread.h>#define BUFFER_SIZE         5       //产品库存大小#define PRODUCT_CNT         50      //产品生产总数 struct product_cons{    int buffer[BUFFER_SIZE];  //生产产品值    pthread_mutex_t lock;     //互斥锁 volatile int    int readpos, writepos;    //读写位置    pthread_cond_t notempty;  //条件变量,非空    pthread_cond_t notfull;   //非满}buffer;void init(struct product_cons *p){    pthread_mutex_init(&p->lock, NULL);     //互斥锁    pthread_cond_init(&p->notempty, NULL);  //条件变量    pthread_cond_init(&p->notfull, NULL);   //条件变量    p->readpos = 0;                         //读写位置    p->writepos = 0;}void fini(struct product_cons *p){    pthread_mutex_destroy(&p->lock);     //互斥锁    pthread_cond_destroy(&p->notempty);  //条件变量    pthread_cond_destroy(&p->notfull);   //条件变量    p->readpos = 0;                      //读写位置    p->writepos = 0;}void cleanup_handler(void *arg){    printf("cleanup_handler exec!\n");    pthread_mutex_t *lock = (pthread_mutex_t*)arg;    pthread_mutex_unlock(lock); //解锁}//存储 一个数据 到 bufferrvoid put(struct product_cons *p, int data) //输入产品子函数{    pthread_mutex_lock(&p->lock); //上锁            /*等待,直到 buffer 不为 满*/    while((p->writepos + 1) % BUFFER_SIZE == p->readpos) //测试空间是否已满    {        printf("producer wait for not full\n");        pthread_cond_wait(&p->notfull, &p->lock); //阻塞等待        //这里,生产者 notfull 等待消费者 pthread_cond_signal(&p->notfull);信号        //如果,消费者发送了 signal 信号,表示有了 空闲    }    p->buffer[p->writepos] = data; //写数据    p->writepos++;    if(p->writepos >= BUFFER_SIZE) //如果写到 尾部,返回        p->writepos = 0;            pthread_cond_signal(&p->notempty); //发送有数据信号    pthread_mutex_unlock(&p->lock); //解锁      }//读,移除 一个数据 从 bufferint get(struct product_cons *p){    int data = 0;    pthread_mutex_lock(&p->lock);    /*等待,直到不为空*/    while(p->writepos == p->readpos)    {        printf("consumer wait for not empty\n");        pthread_cond_wait(&p->notempty,&p->lock);    }    /*读 一个 数据*/    data = p->buffer[p->readpos];            p->readpos++;    if(p->readpos >= BUFFER_SIZE) //如果读到 尾        p->readpos = 0;    pthread_cond_signal(&p->notfull);    pthread_mutex_unlock(&p->lock);    return data;    }void *producer(void *data) //子线程 ,生产{    int n;    for(n = 1; n <= 50; ++n) //生产 50 个产品    {        sleep(1);        printf("put the %d product\n",n);        put(&buffer,n);    }      printf("producer stopped\n");    return NULL;}void *consumer(void *data){    static int cnt = 0;    while(1)    {        sleep(2);        printf("get the %d product\n", get(&buffer));        if(++cnt == PRODUCT_CNT)            break;    }            printf("consumer stopped\n");    return NULL;}int main(int argc, char *argv[]){    pthread_t th_a,th_b;    void *retval;            init(&buffer);            pthread_create(&th_a, NULL, producer, 0);    pthread_create(&th_b, NULL, consumer, 0);    pthread_join(th_a, &retval);    pthread_join(th_b, &retval);    fini(&buffer);    return 0;}

/*多个生产者和单个消费者*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <unistd.h>#include <pthread.h>#define BUFFER_SIZE         5       //产品库存大小#define PRODUCT_CNT         50      //产品生产总数   struct product_cons{    int buffer[BUFFER_SIZE];  //生产产品值    pthread_mutex_t lock;     //互斥锁,控制buffer    int readpos, writepos;    //读写位置    pthread_cond_t notempty;  //条件变量,非空    pthread_cond_t notfull;   //非满    pthread_mutex_t lock2;    //互斥锁,控制cnt    int cnt;                  //完成生产产品数量}buffer;void init(struct product_cons *p){    pthread_mutex_init(&p->lock, NULL);     //互斥锁    pthread_cond_init(&p->notempty, NULL);  //条件变量    pthread_cond_init(&p->notfull, NULL);   //条件变量    p->readpos = 0;                         //读写位置    p->writepos = 0;    pthread_mutex_init(&p->lock2, NULL);    p->cnt = 0;}void fini(struct product_cons *p){    pthread_mutex_destroy(&p->lock);     //互斥锁    pthread_cond_destroy(&p->notempty);  //条件变量    pthread_cond_destroy(&p->notfull);   //条件变量    p->readpos = 0;                      //读写位置    p->writepos = 0;    pthread_mutex_destroy(&p->lock2);        p->cnt = 0;}//存储 一个数据 到 bufferrvoid put(struct product_cons *p, int data) //输入产品子函数{    pthread_mutex_lock(&p->lock); //上锁            /*等待,直到 buffer 不为 满*/    while((p->writepos + 1) % BUFFER_SIZE == p->readpos) //测试空间是否已满    {        printf("producer wait for not full\n");        pthread_cond_wait(&p->notfull, &p->lock); //阻塞等待        //这里,生产者 notfull 等待消费者 pthread_cond_signal(&p->notfull);信号        //如果,消费者发送了 signal 信号,表示有了 空闲    }    p->buffer[p->writepos] = data; //写数据    p->writepos++;    if(p->writepos >= BUFFER_SIZE) //如果写到 尾部,返回        p->writepos = 0;            pthread_cond_signal(&p->notempty); //发送有数据信号    pthread_mutex_unlock(&p->lock); //解锁      }//读,移除 一个数据 从 bufferint get(struct product_cons *p){    int data = 0;    pthread_mutex_lock(&p->lock);    /*等待,直到不为空*/    while(p->writepos == p->readpos)    {        printf("consumer wait for not empty\n");        pthread_cond_wait(&p->notempty,&p->lock);    }    /*读 一个 数据*/    data = p->buffer[p->readpos];            p->readpos++;    if(p->readpos >= BUFFER_SIZE) //如果读到 尾        p->readpos = 0;    pthread_cond_signal(&p->notfull);    pthread_mutex_unlock(&p->lock);    return data;    }void *producer(void *data) //子线程 ,生产{    int flag = -1;    while(1)    {        pthread_mutex_lock(&buffer.lock2);        if(buffer.cnt < PRODUCT_CNT)        {            ++buffer.cnt;            printf("%s put the %d product\n", (char*)data, buffer.cnt);            put(&buffer, buffer.cnt);                    }        else            flag = 0;        pthread_mutex_unlock(&buffer.lock2);        if(!flag)            break;        sleep(2);    }      printf("%s producer stopped\n", (char*)data);    return NULL;}void *consumer(void *data){    int d = 0;    while(1)    {        sleep(1);        d = get(&buffer);        printf("get the %d product\n",d);        if(d == PRODUCT_CNT)            break;    }            printf("consumer stopped\n");    return NULL;}int main(int argc, char *argv[]){    pthread_t th_a[3],th_b;    void *retval;            init(&buffer);            pthread_create(&th_a[0], NULL, producer, (void*)"th_a[0]");    pthread_create(&th_a[1], NULL, producer, (void*)"th_a[1]");        pthread_create(&th_a[2], NULL, producer, (void*)"th_a[2]");    pthread_create(&th_b, NULL, consumer, 0);    pthread_join(th_a[0], &retval);    pthread_join(th_a[1], &retval);    pthread_join(th_a[2], &retval);    pthread_join(th_b, &retval);    fini(&buffer);    return 0;}

/*单个生产者和多个消费者*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <unistd.h>#include <pthread.h>#define BUFFER_SIZE         5       //产品库存大小#define PRODUCT_CNT         50      //产品生产总数  struct product_cons{    int buffer[BUFFER_SIZE];  //生产产品值    pthread_mutex_t lock;     //互斥锁 volatile int    int readpos, writepos;    //读写位置    pthread_cond_t notempty;  //条件变量,非空    pthread_cond_t notfull;   //非满    pthread_mutex_t lock2;    //互斥锁,控制cnt    int cnt;                  //获得生产产品数量}buffer;void init(struct product_cons *p){    pthread_mutex_init(&p->lock, NULL);     //互斥锁    pthread_cond_init(&p->notempty, NULL);  //条件变量    pthread_cond_init(&p->notfull, NULL);   //条件变量    p->readpos = 0;                         //读写位置    p->writepos = 0;    pthread_mutex_init(&p->lock2, NULL);    p->cnt = 0;}void fini(struct product_cons *p){    pthread_mutex_destroy(&p->lock);     //互斥锁    pthread_cond_destroy(&p->notempty);  //条件变量    pthread_cond_destroy(&p->notfull);   //条件变量    p->readpos = 0;                      //读写位置    p->writepos = 0;    pthread_mutex_destroy(&p->lock2);        p->cnt = 0;}//存储 一个数据 到 bufferrvoid put(struct product_cons *p, int data) //输入产品子函数{    pthread_mutex_lock(&p->lock); //上锁            /*等待,直到 buffer 不为 满*/    while((p->writepos + 1) % BUFFER_SIZE == p->readpos) //测试空间是否已满    {        printf("producer wait for not full\n");        pthread_cond_wait(&p->notfull, &p->lock); //阻塞等待        //这里,生产者 notfull 等待消费者 pthread_cond_signal(&p->notfull);信号        //如果,消费者发送了 signal 信号,表示有了 空闲    }    p->buffer[p->writepos] = data; //写数据    p->writepos++;    if(p->writepos >= BUFFER_SIZE) //如果写到 尾部,返回        p->writepos = 0;            pthread_cond_signal(&p->notempty); //发送有数据信号    pthread_mutex_unlock(&p->lock); //解锁      }//读,移除 一个数据 从 bufferint get(struct product_cons *p){    int data = 0;    pthread_mutex_lock(&p->lock);    /*等待,直到不为空*/    while(p->writepos == p->readpos)    {        printf("consumer wait for not empty\n");        pthread_cond_wait(&p->notempty,&p->lock);    }    /*读 一个 数据*/    data = p->buffer[p->readpos];            p->readpos++;    if(p->readpos >= BUFFER_SIZE) //如果读到 尾        p->readpos = 0;    pthread_cond_signal(&p->notfull);    pthread_mutex_unlock(&p->lock);    return data;    }void *producer(void *data) //子线程 ,生产{    int n;    for(n = 1; n <= PRODUCT_CNT; ++n) //生产 50 个产品    {        sleep(1);        printf("put the %d product\n",n);        put(&buffer, n);    }      printf("producer stopped\n");    return NULL;}void *consumer(void *data){    int flag = -1;    while(1)    {        pthread_mutex_lock(&buffer.lock2);        if(buffer.cnt < PRODUCT_CNT)        {            printf("%s get the %d product\n", (char*)data, get(&buffer));            ++buffer.cnt;        }        else            flag = 0;        pthread_mutex_unlock(&buffer.lock2);        if(!flag)            break;        sleep(2);    }            printf("%s consumer stopped\n", (char*)data);    return NULL;}int main(int argc, char *argv[]){    pthread_t th_a,th_b[3];    void *retval;            init(&buffer);            pthread_create(&th_a, NULL, producer, 0);    pthread_create(&th_b[0], NULL, consumer, (void*)"th_b[0]");    pthread_create(&th_b[1], NULL, consumer, (void*)"th_b[1]");    pthread_create(&th_b[2], NULL, consumer, (void*)"th_b[2]");    pthread_join(th_a, &retval);    pthread_join(th_b[0], &retval);    pthread_join(th_b[1], &retval);    pthread_join(th_b[2], &retval);    fini(&buffer);    return 0;}

/*多个生产者和多个消费者*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <unistd.h>#include <pthread.h>#define BUFFER_SIZE         5       //产品库存大小#define PRODUCT_CNT         50      //产品生产总数  struct product_cons{    int buffer[BUFFER_SIZE];  //生产产品值    pthread_mutex_t lock;     //互斥锁 volatile int    int readpos, writepos;    //读写位置    pthread_cond_t notempty;  //条件变量,非空    pthread_cond_t notfull;   //非满    pthread_mutex_t lock2;    //互斥锁,控制cnt_p    int cnt_p;                //完成生产产品数量    pthread_mutex_t lock3;    //互斥锁,控制cnt_c    int cnt_c;                //获得生产产品数量}buffer;void init(struct product_cons *p){    pthread_mutex_init(&p->lock, NULL);     //互斥锁    pthread_cond_init(&p->notempty, NULL);  //条件变量    pthread_cond_init(&p->notfull, NULL);   //条件变量    p->readpos = 0;                         //读写位置    p->writepos = 0;    pthread_mutex_init(&p->lock2, NULL);    p->cnt_p = 0;    pthread_mutex_init(&p->lock3, NULL);    p->cnt_c = 0;}void fini(struct product_cons *p){    pthread_mutex_destroy(&p->lock);     //互斥锁    pthread_cond_destroy(&p->notempty);  //条件变量    pthread_cond_destroy(&p->notfull);   //条件变量    p->readpos = 0;                      //读写位置    p->writepos = 0;    pthread_mutex_destroy(&p->lock2);        p->cnt_p = 0;    pthread_mutex_destroy(&p->lock3);        p->cnt_c = 0;}//存储 一个数据 到 bufferrvoid put(struct product_cons *p, int data) //输入产品子函数{    pthread_mutex_lock(&p->lock); //上锁            /*等待,直到 buffer 不为 满*/    while((p->writepos + 1) % BUFFER_SIZE == p->readpos) //测试空间是否已满    {        printf("producer wait for not full\n");        pthread_cond_wait(&p->notfull, &p->lock); //阻塞等待        //这里,生产者 notfull 等待消费者 pthread_cond_signal(&p->notfull);信号        //如果,消费者发送了 signal 信号,表示有了 空闲    }    p->buffer[p->writepos] = data; //写数据    p->writepos++;    if(p->writepos >= BUFFER_SIZE) //如果写到 尾部,返回        p->writepos = 0;            pthread_cond_signal(&p->notempty); //发送有数据信号    pthread_mutex_unlock(&p->lock); //解锁      }//读,移除 一个数据 从 bufferint get(struct product_cons *p){    int data = 0;    pthread_mutex_lock(&p->lock);    /*等待,直到不为空*/    while(p->writepos == p->readpos)    {        printf("consumer wait for not empty\n");        pthread_cond_wait(&p->notempty,&p->lock);    }    /*读 一个 数据*/    data = p->buffer[p->readpos];            p->readpos++;    if(p->readpos >= BUFFER_SIZE) //如果读到 尾        p->readpos = 0;    pthread_cond_signal(&p->notfull);    pthread_mutex_unlock(&p->lock);    return data;    }void *producer(void *data) //子线程 ,生产{    int flag = -1;    while(1)    {        pthread_mutex_lock(&buffer.lock2);        if(buffer.cnt_p < PRODUCT_CNT)        {            ++buffer.cnt_p;            printf("%s put the %d product\n", (char*)data, buffer.cnt_p);            put(&buffer, buffer.cnt_p);                    }        else            flag = 0;        pthread_mutex_unlock(&buffer.lock2);        if(!flag)            break;        sleep(2);    }      printf("%s producer stopped\n", (char*)data);    return NULL;}void *consumer(void *data){    int flag = -1;    while(1)    {        pthread_mutex_lock(&buffer.lock3);        if(buffer.cnt_c < PRODUCT_CNT)        {            printf("%s get the %d product\n", (char*)data, get(&buffer));            ++buffer.cnt_c;        }        else            flag = 0;        pthread_mutex_unlock(&buffer.lock3);        if(!flag)            break;        sleep(2);    }            printf("%s consumer stopped\n", (char*)data);    return NULL;}int main(int argc, char *argv[]){    pthread_t th_a[3],th_b[3];    void *retval;            init(&buffer);            pthread_create(&th_a[0], NULL, producer, (void*)"th_a[0]");    pthread_create(&th_a[1], NULL, producer, (void*)"th_a[1]");        pthread_create(&th_a[2], NULL, producer, (void*)"th_a[2]");    pthread_create(&th_b[0], NULL, consumer, (void*)"th_b[0]");    pthread_create(&th_b[1], NULL, consumer, (void*)"th_b[1]");    pthread_create(&th_b[2], NULL, consumer, (void*)"th_b[2]");    pthread_join(th_a[0], &retval);    pthread_join(th_a[1], &retval);    pthread_join(th_a[2], &retval);    pthread_join(th_b[0], &retval);    pthread_join(th_b[1], &retval);    pthread_join(th_b[2], &retval);    fini(&buffer);    return 0;}



原创粉丝点击