条件变量实现生产者和消费者

感情迁移 提交于 2020-03-08 22:37:08

条件变量不是锁,但也可以造成线程阻塞,通常与互斥锁配合使用,给多线程提供一个会和的场所
常用函数:
int pthread_cond_destroy(pthread_cond_t *cond);
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
初始化:包括动态初始化和静态初始化

int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
函数作用:
1.阻塞等待条件变量满足
2.释放已掌握的互斥锁(解锁互斥量)
1 2 两步为原子操作
3.当被唤醒, pthread_cond_wait函数返回时,解除阻塞并重新获取互斥锁

int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_signal(pthread_cond_t *cond);
唤醒阻塞在条件变量上的线程

//注意:函数返回值都没有检查,实际需要加上
#include <stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<unistd.h>

//创建一个全局结构体,用来让生产者和消费者访问
struct store{
    int num;
    struct store *next;

};
struct store *head;

//创建一把锁
pthread_mutex_t mutex;
//创建条件变量
pthread_cond_t has_product;

void *producer(void *arg){

    while(1){
        struct store *product;
        product = (struct store*)malloc(sizeof(struct store)); //生产
        product->next = NULL;
        product->num = rand() % 100 + 1;
        printf("producer-------------number=%d\n", product->num);

        pthread_mutex_lock(&mutex);                         //访问前加锁
        product->next = head;
        head = product;
        pthread_mutex_unlock(&mutex);                       //访问完立即解锁

        pthread_cond_signal(&has_product);                  //通知条件满足
        sleep(rand() % 5);
    
    }
    return NULL;
}

void *consumer(void *arg){

    while(1){
        struct store *p;
        
        pthread_mutex_lock(&mutex);                           //注意:先加锁
        if(head->next == NULL)                                     //没有产品,则阻塞在条件变量上
            pthread_cond_wait(&has_product, &mutex);
        p = head;
        head = p->next;
        pthread_mutex_unlock(&mutex);
        
        printf("consumer---------number=%d\n", p->num);
        free(p);
        sleep(rand() % 4);
    }
    return NULL;
}

int main()
{
    head = NULL;
    pthread_t tpid;
    pthread_t tcid;
    srand(time(NULL));

    pthread_mutex_init(&mutex, NULL);            //初始化锁
    pthread_cond_init(&has_product, NULL);       //初始化条件变量

    pthread_create(&tpid, NULL, producer, NULL); //创建生产者线程
    pthread_create(&tcid, NULL, consumer, NULL); //创建消费者线程

    pthread_join(tpid, NULL);
    pthread_join(tcid, NULL);

    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&has_product);

    return 0;
}

运行结果

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!