线程 -- 条件变量 生产者消费者问题

线程 – 条件变量

使用到的函数声明

#include <pthread.h>
// 条件变量不是锁 要和互斥量组合使用
// 超时等待
int pthread_cond_timedwait(pthread_cond_t *restrict cond,
                           pthread_mutex_t *restrict mutex,
                           const struct timespec *restrict abstime);

struct timespec {
    __kernel_time_t tv_sec; /* seconds */	  // 当前时间到1970年1月1日0:0:0的秒数
    long        tv_nsec;    /* nanoseconds */ // 纳秒数
};
// tv_sec 绝对时间,填写时 time(NULL) + 600 ==> 设置超时600秒
// 1s = 1000ms(毫秒)
// 1ms = 1000us(微秒)
// 1us = 1000ns(纳秒)

// 条件变量阻塞等待
int pthread_cond_wait(pthread_cond_t *restrict cond,
                      pthread_mutex_t *restrict mutex);
// 销毁
int pthread_cond_destroy(pthread_cond_t *cond);
// 初始化
int pthread_cond_init(pthread_cond_t *restrict cond,
                      const pthread_condattr_t *restrict attr);
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
// 唤醒阻塞在条件变量cond上的所有线程
int pthread_cond_broadcast(pthread_cond_t *cond);
// 唤醒至少一个阻塞在条件变量cond上的多线程
int pthread_cond_signal(pthread_cond_t *cond);

条件变量的作用:避免没有必要的竞争 。

生产者消费者问题

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#include<pthread.h>

// 定义开始编号
int beginnum = 1;

// 链表结构体
typedef struct _ProdInfo{
    int num;
    struct _ProdInfo *next;
}ProdInfo;

// 定义互斥量
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
// 定义信号量
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

// 定义头节点
ProdInfo *Head = NULL;

// 生产者
void *thr_producter(void *arg)
{
    // 负责链表上添加数据
    while(1){
        ProdInfo * prod = malloc(sizeof(ProdInfo));
        prod->num = beginnum++;

        printf("生产者---%s---%lu---产品编号:%d \n",__FUNCTION__, pthread_self(), prod->num);

        pthread_mutex_lock(&mutex);  // 加锁
        // 加到链表上 头插
        prod->next = Head;
        Head = prod;
        
        pthread_mutex_unlock(&mutex);  // 解锁

        // 发起通知
        pthread_cond_signal(&cond);
        sleep(rand()%2);
    }
    return NULL;
}

// 消费者
void* thr_customer(void *arg)
{
    ProdInfo *prod = NULL;
    while(1){
        // 取链表数据
        pthread_mutex_lock(&mutex);
        // 没有数据
        //if(Head == NULL){
        while(Head == NULL){
            pthread_cond_wait(&cond,&mutex);  // 再次之前先加锁
        }
        prod = Head;
        Head = Head->next;
        printf("消费者---%s---%lu---产品编号:%d \n",__FUNCTION__, pthread_self(), prod->num);
        pthread_mutex_unlock(&mutex);
        sleep(rand()%4);
        free(prod);
    }

    return NULL;
}


int main()
{
    int n = 5,i=0;
    pthread_t tid[n];
    for(i; i<2; i++){
        pthread_create(&tid[i],NULL,thr_producter,NULL);
    }
    for(i; i<n; i++){
        pthread_create(&tid[i],NULL,thr_customer,NULL);
    }
    
    for(i=0; i<n; i++){
        pthread_join(tid[i],NULL);
    }
    
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);

    return 0;
}

运行结果 :

[dai@localhost 06线程-2]$ ./05条件变量
生产者—thr_producter—140630486611712—产品编号:1
生产者—thr_producter—140630478219008—产品编号:2
生产者—thr_producter—140630478219008—产品编号:3
消费者—thr_customer—140630469826304—产品编号:3
消费者—thr_customer—140630453040896—产品编号:2
消费者—thr_customer—140630461433600—产品编号:1
生产者—thr_producter—140630486611712—产品编号:4
生产者—thr_producter—140630486611712—产品编号:5
生产者—thr_producter—140630486611712—产品编号:6
生产者—thr_producter—140630478219008—产品编号:7
消费者—thr_customer—140630453040896—产品编号:7
生产者—thr_producter—140630486611712—产品编号:8
生产者—thr_producter—140630478219008—产品编号:9
生产者—thr_producter—140630478219008—产品编号:10
消费者—thr_customer—140630469826304—产品编号:10
消费者—thr_customer—140630461433600—产品编号:9
^C

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

去留意

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值