【Linux操作系统】Linux系统编程中条件变量实现生产者消费者模型

在Linux系统编程中,条件变量是一种用于线程间同步的机制,常用于实现生产者消费者模型。生产者消费者模型是一种常见的并发编程模型,用于解决多线程环境下的数据共享和同步问题。在该模型中,生产者负责生产数据,消费者负责消费数据,而条件变量则用于在生产者和消费者之间进行同步。

\

文章目录

    • 原理
    • 相关函数
      • [1. pthread_cond_init](#1. pthread_cond_init "#1_pthread_cond_init_14")
      • [2. pthread_cond_destroy](#2. pthread_cond_destroy "#2_pthread_cond_destroy_24")
      • [3. pthread_cond_wait](#3. pthread_cond_wait "#3_pthread_cond_wait_33")
      • [4. pthread_cond_signal](#4. pthread_cond_signal "#4_pthread_cond_signal_43")
      • [5. pthread_cond_broadcast](#5. pthread_cond_broadcast "#5_pthread_cond_broadcast_52")
    • 示例和代码解释

原理

条件变量是一种基于互斥锁的线程同步机制,它允许线程在满足特定条件之前等待,并在条件满足时被唤醒。在生产者消费者模型中,条件变量用于控制生产者和消费者之间的数据传递和同步。

条件变量通常与互斥锁配合使用。互斥锁用于保护共享资源,而条件变量用于在特定条件下等待和唤醒线程。当某个线程需要等待某个条件时,它会释放互斥锁并进入等待状态。当其他线程满足了条件并调用相应的函数来通知等待线程时,等待线程会被唤醒并重新获取互斥锁。

相关函数

1. pthread_cond_init

c 复制代码
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
  • 功能:初始化条件变量

  • 参数:

    • cond:指向条件变量的指针
    • attr:条件变量的属性,通常为NULL
  • 返回值:成功返回0,失败返回错误码

2. pthread_cond_destroy

c 复制代码
int pthread_cond_destroy(pthread_cond_t *cond);
  • 功能:销毁条件变量

  • 参数:

    • cond:指向条件变量的指针
  • 返回值:成功返回0,失败返回错误码

3. pthread_cond_wait

c 复制代码
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
  • 功能:等待条件变量满足

  • 参数:

    • cond:指向条件变量的指针
    • mutex:指向互斥锁的指针
  • 返回值:成功返回0,失败返回错误码

4. pthread_cond_signal

c 复制代码
int pthread_cond_signal(pthread_cond_t *cond);
  • 功能:唤醒等待条件变量的一个线程

  • 参数:

    • cond:指向条件变量的指针
  • 返回值:成功返回0,失败返回错误码

5. pthread_cond_broadcast

c 复制代码
int pthread_cond_broadcast(pthread_cond_t *cond);
  • 功能:唤醒等待条件变量的所有线程

  • 参数:

    • cond:指向条件变量的指针
  • 返回值:成功返回0,失败返回错误码

示例和代码解释

下面是一个使用条件变量实现生产者消费者模型的示例代码:

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define BUFFER_SIZE 10

int buffer[BUFFER_SIZE];
int count = 0;
pthread_mutex_t mutex;
pthread_cond_t cond;

void *producer(void *arg) {
    int i;
    for (i = 0; i < BUFFER_SIZE; i++) {
        pthread_mutex_lock(&mutex);
        while (count == BUFFER_SIZE) {
            pthread_cond_wait(&cond, &mutex);
        }
        buffer[count++] = i;
        printf("Produced: %d\n", i);
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&mutex);
    }
    pthread_exit(NULL);
}

void *consumer(void *arg) {
    int i;
    for (i = 0; i < BUFFER_SIZE; i++) {
        pthread_mutex_lock(&mutex);
        while (count == 0) {
            pthread_cond_wait(&cond, &mutex);
        }
        int item = buffer[--count];
        printf("Consumed: %d\n", item);
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&mutex);
    }
    pthread_exit(NULL);
}

int main() {
    pthread_t producer_thread, consumer_thread;

    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);

    pthread_create(&producer_thread, NULL, producer, NULL);
    pthread_create(&consumer_thread, NULL, consumer, NULL);

    pthread_join(producer_thread, NULL);
    pthread_join(consumer_thread, NULL);

    pthread_cond_destroy(&cond);
    pthread_mutex_destroy(&mutex);

    return 0;
}

上述代码中,我们定义了一个大小为10的缓冲区(buffer),生产者线程负责向缓冲区中生产数据,消费者线程负责从缓冲区中消费数据。

在生产者线程中,我们首先获取互斥锁,然后检查缓冲区是否已满。如果缓冲区已满,则调用pthread_cond_wait函数等待条件变量满足,此时会自动释放互斥锁。当其他线程调用pthread_cond_signal函数唤醒等待的线程时,生产者线程会被唤醒并重新获取互斥锁。然后,我们将数据放入缓冲区,打印生产的数据,并调用pthread_cond_signal函数唤醒可能等待的消费者线程。最后,释放互斥锁。

在消费者线程中,我们也首先获取互斥锁,然后检查缓冲区是否为空。如果缓冲区为空,则调用pthread_cond_wait函数等待条件变量满足,此时会自动释放互斥锁。当其他线程调用pthread_cond_signal函数唤醒等待的线程时,消费者线程会被唤醒并重新获取互斥锁。然后,我们从缓冲区中取出数据,打印消费的数据,并调用pthread_cond_signal函数唤醒可能等待的生产者线程。最后,释放互斥锁。

在主函数中,我们创建了生产者线程和消费者线程,并等待它们的完成。最后,我们销毁条件变量和互斥锁。

通过以上代码和解释,我们可以清楚地了解条件变量在生产者消费者模型中的使用。条件变量的作用是在特定条件满足时等待和唤醒线程,从而实现线程间的同步。同时,结合互斥锁的使用,可以确保线程对共享资源的访问是安全的。

相关推荐
JaneZJW10 小时前
江科大STM32入门——UART通信笔记总结
笔记·stm32·单片机·嵌入式
YunB西风英11 小时前
(STM32笔记)十二、DMA的基础知识与用法 第三部分
笔记·stm32·单片机·嵌入式硬件·dma·嵌入式
JaneZJW2 天前
江科大STM32入门——IIC通信笔记总结
c语言·笔记·stm32·单片机·嵌入式硬件·嵌入式·iic
JaneZJW2 天前
江科大STM32入门——SPI通信笔记总结
笔记·stm32·单片机·嵌入式硬件·嵌入式·spi
网易独家音乐人Mike Zhou2 天前
【TI毫米波雷达】DCA1000不使用mmWave Studio的数据采集方法,以及自动化实时数据采集
c语言·单片机·mcu·物联网·嵌入式·iot·毫米波雷达
pandyele2 天前
单片机死机问题处理
单片机·嵌入式
小仇学长3 天前
嵌入式SD/TF卡通用协议-SDIO协议
嵌入式·sd卡·sdio
JaneZJW3 天前
嵌入式岗位面试八股文(篇三 操作系统(下))
linux·stm32·面试·嵌入式·c
JaneZJW4 天前
嵌入式岗位面试八股文(篇三 操作系统(上))
linux·单片机·面试·操作系统·嵌入式
Bull-man4 天前
LS1046 XFI网口接近10Gbps
linux·arm开发·嵌入式