3.12生产者消费者模型(pthread_cond_t、sem_t)

2023-05-16

生产者消费者模型

生产者不能在容器满了继续生产

消费者不能在容器为空的时候消费

/*
    生产者消费者模型(粗略的版本)
*/
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>

//创建一个互斥量
pthread_mutex_t mutex;

struct Node
{
    int num;
    struct Node *next;
};

//头节点
struct Node *head=NULL;

void *product(void *arg){
    
    //不断的创建新的节点,添加到链表中
    while(1){
        pthread_mutex_lock(&mutex);
        struct Node * newNode = (struct Node*)malloc(sizeof (struct Node));
        newNode->next=head;
        head=newNode;
        newNode->num=rand()%1000;
        printf("add node,num:%d,tid:%ld\n",newNode->num,pthread_self());
        pthread_mutex_unlock(&mutex);
        usleep(100);
    }
    return NULL;
}

void *customer(void *arg){
    while(1){
        pthread_mutex_lock(&mutex);
        struct Node *tmp=head;
        if(head!=NULL){
            head=head->next;
            printf("del node,num %d,tid:%ld\n",tmp->num,pthread_self());
            free(tmp);
            pthread_mutex_unlock(&mutex);
            usleep(100);
        }
        else
        {
            //没有数据
            pthread_mutex_unlock(&mutex);
        }
    }
    return NULL;
}
int main()
{
    pthread_mutex_init(&mutex,NULL);

    //创建5个生产者线程,5个消费者模型
    pthread_t ptids[5],ctids[5];

    for(int i=0;i<5;i++){
        pthread_create(&ptids[i],NULL,product,NULL);
        pthread_create(&ctids[i],NULL,customer,NULL);
    }

    for(int i=0;i<5;i++){
        pthread_detach(ptids[i]);
        pthread_detach(ctids[i]);
    }

    while(1) {
        sleep(10);
    }
    pthread_mutex_destroy(&mutex);

    pthread_exit(NULL);
    return 0;
}

通过设置条件变量来在没有资料的时候消费者等待生产者来生产

/*
    条件变量的类型 pthread_cond_t
    int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
    int pthread_cond_destroy(pthread_cond_t *cond);
    int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
        - 等待,调用了该函数,线程会阻塞。
    int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);
        - 等待多长时间,调用了这个函数,线程会阻塞,直到指定的时间结束。
    int pthread_cond_signal(pthread_cond_t *cond);
        - 唤醒一个或者多个等待的线程
    int pthread_cond_broadcast(pthread_cond_t *cond);
        - 唤醒所有的等待的线程
*/
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>

// 创建一个互斥量
pthread_mutex_t mutex;
// 创建条件变量
pthread_cond_t cond;

struct Node{
    int num;
    struct Node *next;
};

// 头结点
struct Node * head = NULL;

void * producer(void * arg) {

    // 不断的创建新的节点,添加到链表中
    while(1) {
        pthread_mutex_lock(&mutex);
        struct Node * newNode = (struct Node *)malloc(sizeof(struct Node));
        newNode->next = head;
        head = newNode;
        newNode->num = rand() % 1000;
        printf("add node, num : %d, tid : %ld\n", newNode->num, pthread_self());
        
        // 只要生产了一个,就通知消费者消费
        pthread_cond_signal(&cond);

        pthread_mutex_unlock(&mutex);
        usleep(100);
    }

    return NULL;
}

void * customer(void * arg) {

    while(1) {
        pthread_mutex_lock(&mutex);
        // 保存头结点的指针
        struct Node * tmp = head;
        // 判断是否有数据
        if(head != NULL) {
            // 有数据
            head = head->next;
            printf("del node, num : %d, tid : %ld\n", tmp->num, pthread_self());
            free(tmp);
            pthread_mutex_unlock(&mutex);
            usleep(100);
        } else {
            // 没有数据,需要等待
            // 当这个函数调用阻塞的时候,会对互斥锁进行解锁,当不阻塞的,继续向下执行,会重新加锁。
            pthread_cond_wait(&cond, &mutex);
            pthread_mutex_unlock(&mutex);
        }
    }
    return  NULL;
}

int main() {

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

    // 创建5个生产者线程,和5个消费者线程
    pthread_t ptids[5], ctids[5];

    for(int i = 0; i < 5; i++) {
        pthread_create(&ptids[i], NULL, producer, NULL);
        pthread_create(&ctids[i], NULL, customer, NULL);
    }

    for(int i = 0; i < 5; i++) {
        pthread_detach(ptids[i]);
        pthread_detach(ctids[i]);
    }

    while(1) {
        sleep(10);
    }

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

    pthread_exit(NULL);

    return 0;
}

信号量解决

/*
    信号量的类型 sem_t
    int sem_init(sem_t *sem, int pshared, unsigned int value);
        - 初始化信号量
        - 参数:
            - sem : 信号量变量的地址
            - pshared : 0 用在线程间 ,非0 用在进程间
            - value : 信号量中的值

    int sem_destroy(sem_t *sem);
        - 释放资源

    int sem_wait(sem_t *sem);
        - 对信号量加锁,调用一次对信号量的值-1,如果值为0,就阻塞

    int sem_trywait(sem_t *sem);

    int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
    int sem_post(sem_t *sem);
        - 对信号量解锁,调用一次对信号量的值+1

    int sem_getvalue(sem_t *sem, int *sval);

    sem_t psem;
    sem_t csem;
    init(psem, 0, 8);
    init(csem, 0, 0);

    producer() {
        sem_wait(&psem);
        sem_post(&csem)
    }

    customer() {
        sem_wait(&csem);
        sem_post(&psem)
    }

*/

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

// 创建一个互斥量
pthread_mutex_t mutex;
// 创建两个信号量
sem_t psem;
sem_t csem;

struct Node{
    int num;
    struct Node *next;
};

// 头结点
struct Node * head = NULL;

void * producer(void * arg) {

    // 不断的创建新的节点,添加到链表中
    while(1) {
        sem_wait(&psem);
        pthread_mutex_lock(&mutex);
        struct Node * newNode = (struct Node *)malloc(sizeof(struct Node));
        newNode->next = head;
        head = newNode;
        newNode->num = rand() % 1000;
        printf("add node, num : %d, tid : %ld\n", newNode->num, pthread_self());
        pthread_mutex_unlock(&mutex);
        sem_post(&csem);
    }

    return NULL;
}

void * customer(void * arg) {

    while(1) {
        sem_wait(&csem);
        pthread_mutex_lock(&mutex);
        // 保存头结点的指针
        struct Node * tmp = head;
        head = head->next;
        printf("del node, num : %d, tid : %ld\n", tmp->num, pthread_self());
        free(tmp);
        pthread_mutex_unlock(&mutex);
        sem_post(&psem);
       
    }
    return  NULL;
}

int main() {

    pthread_mutex_init(&mutex, NULL);
    sem_init(&psem, 0, 8);
    sem_init(&csem, 0, 0);

    // 创建5个生产者线程,和5个消费者线程
    pthread_t ptids[5], ctids[5];

    for(int i = 0; i < 5; i++) {
        pthread_create(&ptids[i], NULL, producer, NULL);
        pthread_create(&ctids[i], NULL, customer, NULL);
    }

    for(int i = 0; i < 5; i++) {
        pthread_detach(ptids[i]);
        pthread_detach(ctids[i]);
    }

    while(1) {
        sleep(10);
    }

    pthread_mutex_destroy(&mutex);

    pthread_exit(NULL);

    return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

3.12生产者消费者模型(pthread_cond_t、sem_t) 的相关文章

  • Note for Understanding Neural Networks Through Deep Visualization

    Note for Understanding Neural Networks Through Deep Visualization Abstract 近年来 xff0c 在训练大型深度神经网络方面取得了巨大进展 xff0c 其中包括训练卷积
  • ML-Leaks Note

    ML Leaks Model and Data IndependentMembership Inference Attacks and Defenses onMachine Learning Models xff08 机器学习模型上与模型和
  • C++中读取字符串的方式

    这里写自定义目录标题 C 43 43 读取字符串的两种方式1 getline 读取行的输入2 get 读取行的输入 C 43 43 读取字符串的两种方式 1 getline 读取行的输入 getline函数读取整行 xff0c 它使用通过回
  • 二叉树的基本操作

    二叉树 先序和中序确定二叉树 后序以及中序确定二叉树 span class token comment 指针版本 span span class token keyword struct span node span class token
  • 2023秋招面试准备

    2022 秋招资料 算法数据结构 螺旋矩阵问题 螺旋矩阵I 将 1 n m 个数按蛇形方向填入数组中 记录蛇形矩阵偏移量方法 xff0c 四个不同方向右下左上 xff0c 判断什么情况下矩阵遍历完 xff0c 1 要么出界 2 要么走完 s
  • KingbaseES V8R6 维护管理案例之---Kstudio在CentOS 7启动故障

    案例说明 xff1a 在CentOS 7上安装KingbaseES V8R6C006数据库后 xff0c 启动Kstudio图形界面启动失败 xff0c gtk动态库加载失败 xff0c 安装gtk相关动态库后 xff0c 问题解决 适用版
  • python 发送post请求

    背景 浏览器在访问网页时会发送很多http请求 xff08 request xff09 xff0c 服务器返回响应 response xff0c 浏览器拿到响应数据后渲染出来 xff0c 当然我们可以尝试使用python模拟浏览器发送出这些
  • iOS 如何在Label中显示html的文本

    if self messageModel NSString htmlString 61 self messageModel contentText NSAttributedString attrStr1 61 NSAttributedStr
  • Java SpringBoot 集成微信公众号

    微信公众号 申请公众号引入依赖yml配置读取配置文件类WxMaProperties配置文件加载json返回工具类控制层测试号配置以上就完成了哦 xff0c 简单教程Gitee开源地址 申请公众号 注册公众测试号点我 引入依赖 span cl
  • 解决linux python3写入txt文件中换行始终显示"\r\n"

    问题环境 xff1a 在Linux上运行python3脚本远程登录设备 xff0c 远程发送指令 xff0c 并把指令的回显写入文件 出现的问题 xff1a 正常应该显示的换行始终被显示成 r n问题 xff0c 在windows上能够正常
  • linux停止正在执行脚本

    正在执行一个压力测试脚本bench sh xff0c 但是想中途停止进程 xff0c 不再执行了 可以用 ps ef grep 进程名 查出进程 xff0c 然后kill该进程 kill 的用法 xff1a kill xff3b 信号代码
  • 使用fragment实现底部导航菜单栏

    在实现这个功能的过程中 xff0c 走了很多的弯路 xff0c 也花费了较长的时间 xff0c 作为一个新手 xff0c 实现这个功能的过程中 xff0c 分了几个步骤进行尝试 xff0c 首先是会使用fragment xff0c 这个见另
  • TypeError: xxx is not a function

    一 问题描述 1 在使用按钮监听一个事件的时候 xff0c 出现了如下图的错误提示 xff1a 又是这个 34 xxx is not a function 34 这种错误还是会常见到的 xff0c 经过一顿排查 xff0c 最后发现是met
  • linux 防火墙 iptables 命令详解

    iptables是Linux操作系统上的一个防火墙工具 xff0c 它可以控制进入 离开 转发的数据流 xff0c 是Linux服务器安全性的重要保障 下面是iptables命令的详解及相应的示例 xff1a 启动 停止 重启iptable
  • git的使用技巧之“clone的代码找不到下载到哪里了”的解决方法

    clone的代码总是找不到在哪里 xff1f 其实就在当前的目录底下 xff0c 在命令行输入 pwd xff0c 即可找到路径 xff0c 区路径中查一下就找到了 xff0c 但是还是有些麻烦 xff0c 最简单的就是自己设置要下载的位置
  • Linux之Xshell远程连接

    文章目录 一 下载远程连接工具Xshell二 使用Xshell远程连接虚拟机三 设置静态IP xff0c 减少连接操作 总结 一 下载远程连接工具Xshell Xshell是一种远程连接工具 xff0c 可用来远程连接虚拟机 Xshell免
  • 一张图解释FTP协议

  • 2016你配得上更好地自己

    传统里我一直觉得过完春节才是一年结束的时候 xff0c 但是现在慢慢习惯阳历的计算 xff0c 2017年1月1日 xff0c 看着空间里面新年祝福和期待 xff0c 突然觉得这才是过年 2016年就这样走了 xff0c 以后我再也回不到2
  • 【Oracle恢复】关于recover database using backup controlfile与until cancel

    本文主要介绍以下四种恢复 方式的含义与区别 xff1a 0 recover database 或者 recover tablespace recover datafile时 1 recover database using backupco
  • Java SpringBoot实现调用OpenAI ChatGPT的相关接口(详细教程)

    大纲 说明 Java调用OpenAI接口 xff0c Java调用实现ChatGPT聊天 xff0c OpenAIAPI是一个自己封装的OpenAI GPT 3聊天API的Java工具类 xff0c 可用于通过Java代码调用GPT 3模型

随机推荐

  • ODI使用技巧_01利用变量实现增量抽取

    ODI使用技巧 01利用变量实现增量抽取 有时候由于数据量较多 xff0c 我们不想每次都进行全表覆盖 xff0c 如果你的源数据有规律增长的ID或者时间戳 xff0c 就可以使用自定义变量的方式进行增量抽取 进行本章之前需要先做以下前提工
  • WINDOWS2008缓存设置工具,解决系统运行久了因系统缓存造成物理内存占用高僵死的问题

    声明 造成服务器卡死的原因是因为虚拟内存设置过低 请大家设置虚拟内存时不能小于物理内存 比如物理内存8G 虚拟内存不能低于8G 最好是系统默认的物理内存的1 5倍 即12G 浪费点硬盘空间也没办法了 看到有朋友也遇到我们之前一样的问题 ht
  • WINDOWS服务器性能监控器的监视以及邮件预警配置

    http www zihao123 com 1245 html 导语 xff1a Windows性能监视器是Windows自带的性能监视软件 xff0c 提供用于分析系统性能的实时数据 仅从一个单独的控制台 xff0c 即可实时监视应用程序
  • 通过 Oracle 日志文件了解 CRS 的启动过程

    之所以要分享这个主题 xff0c 是因为当我第一次遇见 CRS 无法正常启动的故障时 xff0c 那种无从下手的无力感 xff0c 找不到头绪的慌乱感 xff0c 我至今记忆犹新 我想很多初学者也和那时的我一样 xff0c 面对 CRS 的
  • Oracle 远程 RAC 打造双活数据中心 | 从容灾迈向双活案例分享

    我们都知道 xff0c 容灾系统是指在相隔较远的异地 xff0c 建立两套或多套功能相同的 IT 系统 xff0c 互相之间可以进行健康状态监视和功能切换 xff0c 当一处系统因意外 xff08 如停电 UPS 故障 空调故障 火灾 地震
  • SQL优化之道 - 或许你不知道的10条SQL技巧

    一 一些常见的SQL实践 xff08 1 xff09 负向条件查询不能使用索引 select from order where status 61 0 and stauts 61 1 not in not exists 都不是好习惯 可以优
  • 运维技巧 - 活用临时表隔离冷热数据

    在数据库监控过程中发现考勤数据库上 Employees ControlData存储过程执行时间需 20分钟 这个存储过程逻辑很简单 xff0c 就是打开一个游标 xff0c 做 LOOP循环 xff0c 再删除重复数据 xff0c 结构如下
  • Oracle LogMiner的使用

    1 LogMiner是什么 xff1f Oracle官方文档中 xff0c 对LogMiner的描述 Oracle LogMiner which is part of Oracle Database enables you to query
  • linux服务器硬盘IO读写负载查看

    文章目录 1 首先top命令看下2 xff0c 先用iostat查看磁盘io 是否读写负载很高重要指标 xff1a 3 找出占用io高的进程的工具 iotopIO负荷的压力测试 最近在用spark 向MySQL 倒腾数据 xff0c 发现s
  • PreparedStatement与Statement的区别及优势

    PreparedStatement是用来执行SQL查询语句的API之一 xff0c Java提供了 Statement PreparedStatement 和 CallableStatement三种方式来执行查询语句 xff0c 其中 St
  • Mac Idea卡顿、慢解决方案 限制jvm也没有用【超实用】

    前置 Mac使用idea卡顿 不流畅解决方案 xff0c 设置了jvm也没有用 快捷键提示超级慢的问题 导致原因 下载的软件版本问题 去下载标注的版本就变得非常的流畅 xff0c 超级快 版本说明 xff1a 第一个是英特尔芯片的软件 第二
  • HDFS 启动与关闭

    一 HDFS 启动与关闭 HDFS 和普通的硬盘上的文件系统不一样 xff0c 是通过Java 虚拟机运行在整个集群当中的 xff0c 所以当Hadoop 程序写好之后 xff0c 需要启动HDFS 文件系统 xff0c 才能运行 HDFS
  • Android快速入门之通过Fragment实现底部菜单栏

    早期Android应用通常使用TabHost实现页面之间的切换 xff0c 现在更多的选择ViewPager与Fragment结合的方式实现页面切换 Android提供了专门的适配器 FragmentPagerAdapter和Fragmen
  • Zemax操作35--双高斯镜头优化

    要求 xff1a 双高斯镜头是传统的单反相机镜头 相对孔径 xff1a 1 3 焦距 xff1a 75mm 可见光 视场由一个圆定义 xff0c 圆的直径是胶片的对角线 xff0c 像高21 6mm 畸变小于1 玻璃的边界条件最小边缘 中心
  • C/C++编程题之删除字符串中出现次数最少的字符

    在牛客上刷到删除字符串中出现次数最少的字符 xff0c 现在将通过的代码贴一下 xff0c 供大家参考 实现删除字符串中出现次数最少的字符 xff0c 若多个字符出现次数一样 xff0c 则都删除 输出删除这些单词后的字符串 xff0c 字
  • springboot解决servlet-api-2.5.jar和tomcat-embed-core-9.0.46.jar冲突

    2022 11 04 18 07 52 869 ERROR 86604 restartedMain o s b d LoggingFailureAnalysisReporter APPLICATION FAILED TO START Des
  • PS 修改图片大小

    平常的网络世界中 xff0c 会有一些高清晰的图片出现 xff0c 哦不 xff0c 现在的图片越来越超清了 xff1b 那么 xff0c 就需要对它们大小进行修改 xff0c 不然内存伤不起啊 xff01 以下是三种常用的方法 1 修改图
  • 将若依(RuoYI)项目打包(jar)部署到Linux服务器(详细步骤)

    第一步下载maven方便将RuoYi项目打包 1 下载网址 xff1a http maven apache org download cgi 2 3 下载3 6 3版本 解压完成后 将文件夹名称修改为maven 第二步配置maven环境变量
  • 最通俗易懂的乐观锁与悲观锁原理及实现

    一 乐观锁 总是认为不会产生并发问题 xff0c 每次去取数据的时候总认为不会有其他线程对数据进行修改 xff0c 因此不会上锁 xff0c 但是在更新时会判断其他线程在这之前有没有对数据进行修改 xff0c 一般会使用版本号机制或CAS操
  • 3.12生产者消费者模型(pthread_cond_t、sem_t)

    生产者消费者模型 生产者不能在容器满了继续生产 消费者不能在容器为空的时候消费 生产者消费者模型 粗略的版本 include lt stdio h gt include lt pthread h gt include lt stdlib h