首页 > 其他分享 >生产者与消费者模型

生产者与消费者模型

时间:2023-09-17 14:58:20浏览次数:29  
标签:消费者 生产者 模型 int 线程 pthread 缓冲区 mutex sem

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

#define BUFF_MAX 10
#define SC_NUM 2
#define XF_MAX 3

int buff[BUFF_MAX];
int in = 0;
int out = 0;

sem_t sem_empty;
sem_t sem_full;
pthread_mutex_t mutex;

void *sc_thread(void *arg)
{
    int index = (int)arg;
    for (int i = 0; i < 30; i++)
    {
        sem_wait(&sem_empty); // 是否有空闲位置
        pthread_mutex_lock(&mutex);
        buff[in] = rand() % 100;
        printf("第%d个线程,产生数据:%d,在%d位置\n", index, buff[in], in);
        in = (in + 1) % BUFF_MAX;
        pthread_mutex_unlock(&mutex); // 解锁
        sem_post(&sem_full);          // 数据的个数

        int n = rand() % 10;
        sleep(n);
    }
}

void *xf_thread(void *arg)
{
    int index = (int)arg;
    for (int i = 0; i < 20; i++)
    {
        sem_wait(&sem_full);
        pthread_mutex_lock(&mutex);
        printf("-----第%d个线程,消费数据:%d,在%d位置\n", index, buff[out], out);
        out = (out + 1) % BUFF_MAX;
        pthread_mutex_unlock(&mutex);
        sem_post(&sem_empty);

        int n = rand() % 10;
        sleep(n);
    }
}

int main()
{
    sem_init(&sem_empty, 0, BUFF_MAX);
    sem_init(&sem_full, 0, 0);
    pthread_mutex_init(&mutex, NULL);

    srand((int)time(NULL));

    pthread_t sc_id[SC_NUM];
    pthread_t xf_id[XF_NUM];

    for (int i = 0; i < SC_NUM; i++)
    {
        pthread_create(&sc_id[i], NULL, sc_thread, (void *)i); // 创建生产者
    }
    for (int i = 0; i < XF_NUM; i++)
    {
        pthread_create(&xf_id[i], NULL, xf_thread, NULL); // 创建消费者
    }

    for (int i = 0; i < SC_NUM; i++)
    {
        pthread_join(sc_id[i], NULL);
    }
    for (int i = 0; i < XF_NUM; i++)
    {
        pthread_join(xf_id[i], NULL);
    }

    sem_destroy(&sem_empty);
    sem_destroy(&sem_full);
    pthread_mutex_destroy(&mutex);

    printf("main over\n");
    exit(0);
}

这段代码实现了一个生产者-消费者模型,使用了线程和信号量来进行同步。这种模型用于描述两种类型的线程:生产者线程生成数据并将其放入一个共享缓冲区,而消费者线程从缓冲区中获取数据并进行处理。

以下是代码的主要流程解释:

  1. 包含头文件和定义常量: 代码开始包含了必要的头文件,并定义了一些常量,如缓冲区的最大大小 BUFF_MAX,生产者线程数量 SC_NUM,和消费者线程数量 XF_MAX

  2. 全局变量和同步对象初始化: 代码定义了一些全局变量,包括一个整数数组 buff(用于模拟共享缓冲区)、inout(用于记录生产者和消费者在缓冲区中的位置)。此外,代码还初始化了三个同步对象:sem_empty 用于追踪空闲缓冲区位置的信号量,sem_full 用于追踪填充缓冲区位置的信号量,以及 mutex 用于保护对共享资源的互斥访问。

  3. 生产者线程函数 sc_thread 这个函数模拟生产者的行为。每个生产者线程在一个循环中运行,它尝试获取一个空闲的位置,生成一个随机数,将该数放入共享缓冲区,并在完成后释放一个填充的位置。生产者线程也会随机休眠一段时间,以模拟生产的不确定性。

  4. 消费者线程函数 xf_thread 这个函数模拟消费者的行为。每个消费者线程也在一个循环中运行,它尝试获取一个填充的位置,从共享缓冲区中获取数据,处理数据,然后释放一个空闲的位置。和生产者线程一样,消费者线程也会随机休眠一段时间。

  5. 主函数 main 在主函数中,首先对信号量和互斥锁进行初始化。然后,创建了多个生产者线程和消费者线程,它们并发地执行 sc_threadxf_thread 函数。随后,主函数等待所有线程完成,最后销毁了信号量和互斥锁。

  6. 线程的执行: 在执行过程中,生产者线程不断生成数据并放入缓冲区,而消费者线程从缓冲区中取出数据进行处理。信号量 sem_emptysem_full 用于确保生产者和消费者之间的同步。互斥锁 mutex 用于保护对缓冲区的并发访问,确保一次只有一个线程可以修改缓冲区。

  7. 清理和结束: 在所有线程完成后,代码销毁了信号量和互斥锁,然后结束程序。

这段代码演示了如何使用信号量和互斥锁来解决生产者-消费者问题,确保多个线程能够正确地协同工作,避免了竞态条件和数据不一致性问题。

标签:消费者,生产者,模型,int,线程,pthread,缓冲区,mutex,sem
From: https://www.cnblogs.com/keep--fighting/p/17708740.html

相关文章

  • Java内存模型
    Java内存模型(JavaMemoryModel,JMM)定义了Java程序在多线程环境下如何与主内存和工作内存交互的规范。JMM规定了变量的可见性、原子性和顺序性等方面的规则,保证了多线程程序的正确性和可靠性。Java内存模型包括以下几个核心概念:主内存(MainMemory):主内存是Java虚拟机中线程共享......
  • Llama2-Chinese项目:2.2-大语言模型词表扩充
      因为原生LLaMA对中文的支持很弱,一个中文汉子往往被切分成多个token,因此需要对其进行中文词表扩展。思路通常是在中文语料库上训练一个中文tokenizer模型,然后将中文tokenizer与LLaMA原生tokenizer进行合并,最终得到一个扩展后的tokenizer模型。国内Chinese-LLaMA-Alpaca开源项目......
  • 5.进程线程模型你知道多少?
    5.进程线程模型你知道多少?1.进程进程创建与结束背景知识:进程有两种创建方式,一种是操作系统创建的一种是父进程创建的。从计算机启动到终端执行程序的过程为:0号进程->1号内核进程->1号用户进程(init进程)->getty进程->shell进程->命令行执行进程。所以......
  • 深度学习模型压缩方法概述
    一,模型压缩技术概述知识蒸馏算法整体的框架图如图下所示。图片来源https://intellabs.github.io/distiller/knowledge_distillation.html。三,轻量级模型架构四,模型剪枝模型剪枝(modelpruning)也叫模型稀疏化(modelsparsity)。深度学习模型中一般存在着大量冗余的参数,将权重矩阵中......
  • 相机成像模型
    详细推导了相机成像模型。小孔成像小孔成像是初中物理知识,如图所示,蜡烛发出的光线经过小孔投射在光屏上呈现出倒立的实像。以上成像过程涉及三个重要对象,即物点(蜡烛本身)、光心(小孔)、像点(光屏上的亮点),三者连起来的直线叫做光路。小孔成像是理想条件下的相机成像模型。......
  • MVP模型
    MVP模型:1.概念:MVP是一种敏捷模型,精益创业术语"最小可行产品"(MinimumViabeProduct)的简称.用最快、最简明的方式建立一个可用的产品模型,推向市场,测试用户是否喜欢这个产品,进而迭代完善细节.利用MVP模型,可以低成本试错和反复的成本.2.注意事项:不能成为产品定位不清晰、......
  • 如何成功将 API 客户的 transformer 模型推理速度加快 100 倍
    ......
  • python开发商品扫描录入模型
       最近市场监管部门加大了对销售过期商品的处罚力度。很多菜店、粮店等店不大但商品品种、货号批次却非常多。这里介绍两个可以用手机扫描录入商品数据的模型,供大家二次开发,设计出一个管理商品失效日期的小程序。   模型一importsqlite3frompyzbar.pyzbarimport......
  • halcon AI读取onnx模型并推理
    *程序功能:读取onnx模型并推理dev_update_off()dev_close_window()read_dl_model('squeezenet.onnx',DLModelHandle)set_dl_model_param(DLModelHandle,'type','classification')get_dl_model_param(DLModelHandle,'image_dimensions',......
  • Python并发编程——IO模型、阻塞IO、非阻塞IO、多路复用、异步IO、IO模型比较、select
    文章目录每日测验一IO模型介绍二阻塞IO(blockingIO)三非阻塞IO(non-blockingIO)四多路复用IO(IOmultiplexing)五异步IO(AsynchronousI/O)六IO模型比较分析七selectors模块网络并发知识点梳理网络并发知识点梳理每日测验简述死锁现象你用过哪些队列阐述进......