计算机操作系统基础十四线程同步之条件变量

36次阅读

共计 1471 个字符,预计需要花费 4 分钟才能阅读完成。

引言

本文为第十四篇,线程同步之条件变量 ,在上一篇文章是介绍了读写锁,读写锁在多读少写的情况下,性能要强于互斥量。本篇再介绍一种重要的处理线程同步的方法 — 条件变量

条件变量

  • 条件变量是一种相对复杂的线程同步方法
  • 条件变量允许线程睡眠,直到满足某种条件
  • 当满足条件时,可以向该线程发送信号,通知唤醒线程

对于前边所介绍的生产者 - 消费者模型,其实是有一定的漏洞的

  • 当缓冲区小于 0 时,不允许消费者消费,消费者必须等待
  • 当缓冲区满时,不允许生产者往缓冲区生产,生产者必须等待

在前边的文章中并没有对这个进行约束,在本文学习条件变量时,将对这个进行更严谨的约束

假设此时缓冲区等于 0,当生产者生产一个产品时,唤醒可能等待的消费者 。假设缓冲区满时, 当消费者消费一个产品时,唤醒可能等待的生产者

条件变量的示例(需要配合互斥量来使用)

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<vector>
#include<queue>

// 临界资源
int num=0;
// 缓冲区最大值
int MAX_BUF=100;
// 定义条件变量
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
// 定义互斥量
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;

void* producer(void*){while(true){pthread_mutex_lock(&mutex);
        while(num>=MAX_BUF){
            // 等待
            pthread_cond_wait(&cond, &mutex);
            printf("缓冲区满了,等待消费者消费 \n");
        }
        num+=1;
        printf("生产一个产品,当前产品数量为:%d", num);
        sleep(1);// 生产产品所需时间
        // 通知可能等待的消费者
        pthread_cond_signal(&cond);
        printf("通知消费者...\n");
        // 解锁
        pthread_mutex_unlock(&mutex);
        sleep(1); 生产产品的频率
    }
}

void* consumer(void*){while(true){pthread_mutex_lock(&mutex);
        while(num<=0){
            // 等待
            pthread_cond_wait(&cond, &mutex);
       printf("缓冲区空了,等待生产者生产 \n");     
        }
        num-=1;
        printf("消费一个产品,当前产品数量为:%d", num);
        sleep(1);
        // 通知可能等待的生产者
        pthread_cond_signal(&cond);
        printf("通知生产者...\n");
        // 解锁
        pthread_mutex_unlock(&mutex);
    }
}

int main()
{
        // 定义两个线程
        pthread_t thread1,thread2;
        // 一个执行生产者逻辑,一个执行消费者逻辑
        pthread_create(&thread1, NULL, &producer, NULL);
        pthread_create(&thread2, NULL, &consumer, NULL);
        pthread_join(&thread1, NULL);
        pthread_join(&thread2, NULL);
        
        return 0;
}

执行结果:

在快速变化的技术中寻找不变,才是一个技术人的核心竞争力。知行合一,理论结合实践

正文完
 0