电子商务网站开发语言占比/东莞网站推广行者seo08

电子商务网站开发语言占比,东莞网站推广行者seo08,一个小程序商城需要多少钱,贵阳seo网站建设Linux生产者消费者模型 Linux生产者消费者模型详解生产者消费者模型生产者消费者模型的概念生产者消费者模型的特点生产者消费者模型优点 基于BlockingQueue的生产者消费者模型基于阻塞队列的生产者消费者模型模拟实现基于阻塞队列的生产消费模型基础实现生产者消费者步调调整条…

Linux生产者消费者模型

  • Linux生产者消费者模型详解
    • 生产者消费者模型
      • 生产者消费者模型的概念
      • 生产者消费者模型的特点
      • 生产者消费者模型优点
    • 基于BlockingQueue的生产者消费者模型
      • 基于阻塞队列的生产者消费者模型
      • 模拟实现基于阻塞队列的生产消费模型
        • 基础实现
        • 生产者消费者步调调整
        • 条件唤醒优化
        • 基于计算任务的扩展
    • 总结


Linux生产者消费者模型详解


生产者消费者模型

生产者消费者模型的概念

生产者消费者模型通过一个容器解决生产者与消费者的强耦合问题。

  • 通信方式:生产者不直接与消费者交互,而是将数据放入容器;消费者从容器取数据。
  • 容器作用:缓冲区,解耦生产者与消费者,平衡双方处理能力。

生产者消费者模型的特点

生产者消费者模型是多线程同步与互斥的经典场景,具有以下特点:

  1. 三种关系
    • 生产者与生产者:互斥(竞争容器访问)。
    • 消费者与消费者:互斥(竞争容器访问)。
    • 生产者与消费者:互斥(共享容器)+同步(生产消费顺序)。
  2. 两种角色:生产者与消费者(线程或进程)。
  3. 一个交易场所:内存缓冲区(如队列)。

互斥原因:容器是临界资源,需用互斥锁保护,多线程竞争访问。
同步原因

  • 容器满时,生产者需等待,避免生产失败。
  • 容器空时,消费者需等待,避免消费失败。
  • 同步确保有序访问,防止饥饿,提高效率。

注意:互斥保证数据正确性,同步实现线程协作。

生产者消费者模型优点

  1. 解耦:生产者与消费者独立运行,通过容器间接交互。
  2. 支持并发:生产者生产时,消费者可同时消费。
  3. 支持忙闲不均:容器缓冲数据,平衡处理速度差异。

对比函数调用(紧耦合),生产者消费者模型是松耦合设计,生产者无需等待消费者处理。


基于BlockingQueue的生产者消费者模型

基于阻塞队列的生产者消费者模型

在多线程编程中,**阻塞队列(Blocking Queue)**是实现生产者消费者模型的常用数据结构。

  • 与普通队列的区别
    • 队列空时,取元素操作阻塞,直到有数据。
    • 队列满时,放元素操作阻塞,直到有空间。
  • 应用场景:类似管道通信。

模拟实现基于阻塞队列的生产消费模型

基础实现

以单生产者、单消费者为例,使用C++ queue 实现阻塞队列:

BlockQueue.hpp

#pragma once
#include <iostream>
#include <pthread.h>
#include <queue>#define NUM 5template<class T>
class BlockQueue {
private:bool IsFull() { return _q.size() == _cap; }bool IsEmpty() { return _q.empty(); }
public:BlockQueue(int cap = NUM) : _cap(cap) {pthread_mutex_init(&_mutex, nullptr);pthread_cond_init(&_full, nullptr);pthread_cond_init(&_empty, nullptr);}~BlockQueue() {pthread_mutex_destroy(&_mutex);pthread_cond_destroy(&_full);pthread_cond_destroy(&_empty);}void Push(const T& data) {pthread_mutex_lock(&_mutex);while (IsFull()) {pthread_cond_wait(&_full, &_mutex); // 队列满,等待}_q.push(data);pthread_mutex_unlock(&_mutex);pthread_cond_signal(&_empty); // 唤醒消费者}void Pop(T& data) {pthread_mutex_lock(&_mutex);while (IsEmpty()) {pthread_cond_wait(&_empty, &_mutex); // 队列空,等待}data = _q.front();_q.pop();pthread_mutex_unlock(&_mutex);pthread_cond_signal(&_full); // 唤醒生产者}
private:std::queue<T> _q; // 阻塞队列int _cap; // 容量上限pthread_mutex_t _mutex; // 互斥锁pthread_cond_t _full; // 满条件变量pthread_cond_t _empty; // 空条件变量
};

main.cpp

#include "BlockQueue.hpp"
#include <unistd.h>void* Producer(void* arg) {BlockQueue<int>* bq = (BlockQueue<int>*)arg;while (true) {sleep(1);int data = rand() % 100 + 1;bq->Push(data);std::cout << "Producer: " << data << std::endl;}return nullptr;
}
void* Consumer(void* arg) {BlockQueue<int>* bq = (BlockQueue<int>*)arg;while (true) {sleep(1);int data;bq->Pop(data);std::cout << "Consumer: " << data << std::endl;}return nullptr;
}
int main() {srand((unsigned int)time(nullptr));pthread_t producer, consumer;BlockQueue<int>* bq = new BlockQueue<int>;pthread_create(&producer, nullptr, Producer, bq);pthread_create(&consumer, nullptr, Consumer, bq);pthread_join(producer, nullptr);pthread_join(consumer, nullptr);delete bq;return 0;
}

说明

  • 单生产者单消费者:无需维护生产者间或消费者间的互斥。
  • 互斥_mutex 保护队列。
  • 同步_full_empty 条件变量控制生产消费顺序。
  • 条件判断:用 while 防止伪唤醒。
  • 运行结果:生产者与消费者步调一致,每秒交替生产消费。
生产者消费者步调调整
  1. 生产快,消费慢

    void* Producer(void* arg) {BlockQueue<int>* bq = (BlockQueue<int>*)arg;while (true) {int data = rand() % 100 + 1;bq->Push(data);std::cout << "Producer: " << data << std::endl;}
    }
    void* Consumer(void* arg) {BlockQueue<int>* bq = (BlockQueue<int>*)arg;while (true) {sleep(1);int data;bq->Pop(data);std::cout << "Consumer: " << data << std::endl;}
    }
    
    • 生产者快速填满队列后等待,消费者消费一个后唤醒生产者,后续步调一致。
  2. 生产慢,消费快

    void* Producer(void* arg) {BlockQueue<int>* bq = (BlockQueue<int>*)arg;while (true) {sleep(1);int data = rand() % 100 + 1;bq->Push(data);std::cout << "Producer: " << data << std::endl;}
    }
    void* Consumer(void* arg) {BlockQueue<int>* bq = (BlockQueue<int>*)arg;while (true) {int data;bq->Pop(data);std::cout << "Consumer: " << data << std::endl;}
    }
    
    • 消费者初始等待生产者生产,消费后继续等待,步调随生产者。
条件唤醒优化

调整唤醒条件,例如队列数据量超一半时唤醒消费者,小于一半时唤醒生产者:

void Push(const T& data) {pthread_mutex_lock(&_mutex);while (IsFull()) {pthread_cond_wait(&_full, &_mutex);}_q.push(data);if (_q.size() >= _cap / 2) {pthread_cond_signal(&_empty); // 超一半唤醒消费者}pthread_mutex_unlock(&_mutex);
}
void Pop(T& data) {pthread_mutex_lock(&_mutex);while (IsEmpty()) {pthread_cond_wait(&_empty, &_mutex);}data = _q.front();_q.pop();if (_q.size() <= _cap / 2) {pthread_cond_signal(&_full); // 少于一半唤醒生产者}pthread_mutex_unlock(&_mutex);
}
  • 效果:生产者快速填满队列后等待,消费者消费至一半以下才唤醒生产者。
基于计算任务的扩展

将队列存储类型改为任务类,扩展功能:

Task.hpp

#pragma once
#include <iostream>class Task {
public:Task(int x = 0, int y = 0, char op = 0) : _x(x), _y(y), _op(op) {}void Run() {int result = 0;switch (_op) {case '+': result = _x + _y; break;case '-': result = _x - _y; break;case '*': result = _x * _y; break;case '/': if (_y == 0) { std::cout << "Warning: div zero!" << std::endl; result = -1; }else { result = _x / _y; } break;case '%': if (_y == 0) { std::cout << "Warning: mod zero!" << std::endl; result = -1; }else { result = _x % _y; } break;default: std::cout << "error operation!" << std::endl; break;}std::cout << _x << " " << _op << " " << _y << "=" << result << std::endl;}
private:int _x, _y;char _op;
};

main.cpp

#include "BlockQueue.hpp"
#include "Task.hpp"void* Producer(void* arg) {BlockQueue<Task>* bq = (BlockQueue<Task>*)arg;const char* ops = "+-*/%";while (true) {int x = rand() % 100;int y = rand() % 100;char op = ops[rand() % 5];Task t(x, y, op);bq->Push(t);std::cout << "Producer task done" << std::endl;}return nullptr;
}
void* Consumer(void* arg) {BlockQueue<Task>* bq = (BlockQueue<Task>*)arg;while (true) {sleep(1);Task t;bq->Pop(t);t.Run();}return nullptr;
}
int main() {srand((unsigned int)time(nullptr));pthread_t producer, consumer;BlockQueue<Task>* bq = new BlockQueue<Task>;pthread_create(&producer, nullptr, Producer, bq);pthread_create(&consumer, nullptr, Consumer, bq);pthread_join(producer, nullptr);pthread_join(consumer, nullptr);delete bq;return 0;
}
  • 功能:生产者生成计算任务,消费者执行计算并输出结果。
  • 扩展性:通过定义不同 Task 类实现多样化任务处理。

总结

  • 模型核心:通过容器解耦生产者与消费者,支持并发与忙闲不均。
  • 实现关键:阻塞队列结合互斥锁与条件变量,确保互斥与同步。
  • 灵活性:可调整步调、唤醒条件,或扩展为复杂任务处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/898808.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【中文翻译】第9章-The Algorithmic Foundations of Differential Privacy

由于GitHub项目仅翻译到前5章&#xff0c;我们从第6章开始通过大语言模型翻译&#xff0c;并导出markdown格式。 大模型难免存在错漏&#xff0c;请读者指正。 教材原文地址&#xff1a;https://www.cis.upenn.edu/~aaroth/Papers/privacybook.pdf 9 差分隐私与计算复杂度 到目…

【AI大模型】搭建本地大模型GPT-NeoX:详细步骤及常见问题处理

搭建本地大模型GPT-NeoX:详细步骤及常见问题处理 GPT-NeoX是一个开源的大型语言模型框架,由EleutherAI开发,可用于训练和部署类似GPT-3的大型语言模型。本指南将详细介绍如何在本地环境中搭建GPT-NeoX,并解决过程中可能遇到的常见问题。 1. 系统要求 1.1 硬件要求 1.2 软…

Unity跨平台构建快速回顾

知识点来源&#xff1a;人间自有韬哥在&#xff0c;豆包 目录 一、发布应用程序1. 修改发布必备设置1.1 打开设置面板1.2 修改公司名、游戏项目名、版本号和默认图标1.3 修改 Package Name 和 Minimum API Level 2. 发布应用程序2.1 配置 Build Settings2.2 选择发布选项2.3 构…

低配电脑畅玩《怪物猎人:荒野》,ToDesk云电脑优化从30帧到144帧?

《怪物猎人&#xff1a;荒野&#xff08;Monster Hunter Wilds&#xff09;》自2025年正式发售以来已取得相当亮眼的成绩&#xff0c;仅用三天时间便轻松突破800万销量&#xff0c;目前顺利蝉联周榜冠军&#xff1b;凭借着开放世界的宏大场景和丰富的狩猎玩法&#xff0c;该游戏…

Flink基础简介和安装部署

文章目录 一、Flink基础简介1、什么是Flink2、Flink流处理特性3、Flink四大基石4、Flink中的角色 二、Flink集群搭建1、Local模式①上传Flink安装包②启动交互窗口③提交任务测试④访问WebUI页面查看④退出停止集群 一、Flink基础简介 1、什么是Flink Flink是⼀个分布式&#…

【2025】基于ssm+jsp的二手商城系统设计与实现(源码、万字文档、图文修改、调试答疑)

基于SSMJSP的二手商城系统设计与实现系统功能结构图&#xff1a; 课题背景 随着经济的发展和人们生活水平的提高&#xff0c;二手交易市场日益活跃。人们对于闲置物品的处理方式逐渐从传统的废品回收转变为通过二手交易平台进行再利用。这种交易模式不仅能够帮助用户节省开支&a…

幻影星空亮相CAAPA北京展 引领文旅产业升级转型

3月19日&#xff0c;中国游艺机游乐园协会&#xff08;CAAPA&#xff09;主办的2025中国&#xff08;北京&#xff09;国际游乐设施设备博览会及2025北京国际旅游休闲娱乐产业博览会在北京盛大启幕。在这场行业盛会上&#xff0c;广州卓远旗下的“幻影星空”品牌以创新性的虚拟…

银河麒麟桌面版包管理器(二)

以下内容摘自《银河麒麟操作系统进阶应用》一书 APT包管理器 APT是Debian及其派生系统的包管理器&#xff0c;构建在dpkg之上&#xff0c;以其强大的依赖性处理能力和丰富的软件仓库而闻名。APT具有自动解决依赖关系、提供易于使用的命令行工具&#xff08;如apt-get、apt-ca…

Xcode16.1使用MonkeyDev运行Tiktok报错分析

问题1&#xff1a; Build input files cannot be found: /usr/lib/libc.dylib, /usr/lib/libstdc.dylib. Did you forget to declare these files as outputs of any script phases or custom build rules which produce them? 解决办法&#xff1a;在TARGETS的dylib中的Bui…

手机怎么换网络IP有什么用?操作指南与场景应用‌

在数字化时代&#xff0c;手机已经成为我们日常生活中不可或缺的一部分&#xff0c;无论是工作、学习还是娱乐&#xff0c;手机都扮演着至关重要的角色。而在手机的使用过程中&#xff0c;网络IP地址作为设备在互联网上的唯一标识符&#xff0c;其重要性和作用不容忽视。本文将…

CH32V208GBU6沁恒协议栈BUG:在主机Write的同一包notify会造成主机一直Write不成功

从事嵌入式单片机的工作算是符合我个人兴趣爱好的,当面对一个新的芯片我即想把芯片尽快搞懂完成项目赚钱,也想着能够把自己遇到的坑和注意事项记录下来,即方便自己后面查阅也可以分享给大家,这是一种冲动,但是这个或许并不是原厂希望的,尽管这样有可能会牺牲一些时间也有哪天原…

unsloth微调QwQ32B(4bit)

unsloth微调QwQ32B(4bit) GPU: 3090 24G unsloth安装部署 pip 安装 pip install unsloth --index https://pypi.mirrors.usrc.edu.cn/simplesource /etc/network_turbopip install --force-reinstall --no-cache-dir --no-deps githttps://github.com/unslothai/unsloth.git​…

Dify 0.15.3 输入变量无法被重新赋值问题-解决方法

目录 一、问题描述 二、解决方法 2.1 原因 2.2 修改源码 2.3 重新打包 dify-api 镜像 2.4 修改 docker-compose.yaml 文件 2.5 重启启动镜像 一、问题描述 Dify 0.15.3 是一个比较稳定的版本&#xff0c;Dify 1.0 是一个大版本更新&#xff0c;目前还有很多 Bug。但是&a…

SQL Server查询计划操作符(7.3)——查询计划相关操作符(11)

7.3. 查询计划相关操作符 98&#xff09;Table Scan&#xff1a;该操作符从查询计划参数列确定的表中获取所有数据行。如果其参数列中出现WHERE:()谓词&#xff0c;则只返回满足该谓词的数据行。该操作符为逻辑操作符和物理操作符。该操作符具体如图7.3-98节点1所示。 图 7.3-…

数据库练习2

目录 1.向heros表中新增一列信息&#xff0c;添加一些约束&#xff0c;并尝试查询一些信息 2.课堂代码练习 插入语句 INSERT INTO 删除语句DELETE和TRUNCATE 更新语句UPDATE和replace 查询语句SELECT 条件查询 select语句中的特殊情况 ​​​查询排序 order by 分组查询…

资金管理策略思路

详细描述了完整交易策略的实现细节&#xff0c;主要包括输入参数、变量定义、趋势判断、入场与出场条件、止损与止盈设置等多个方面。 输入参数&#xff08;Input&#xff09;&#xff1a; EntryFrL (.6)&#xff1a;多头入场的前一日波动范围的倍数。 EntryFrS (.3)&#xff1…

数据模型,数据建模,组件,核心价值,使用,意义

数据模型 一组由符号,文本组成的集合, 用以准确表达信息景观, 达到有效交流,沟通的目的 数据建模 是发现,分析和确定数据需求的过程,是一种称为数据模型的精确形式表示和传递这些需求 数据模型的组件 实体, 关系, 属性和域 数据模型的核心价值 交流性 精确性 数据模型的…

解锁云原生后端开发新姿势:腾讯云大模型API实战攻略

目录 云原生后端与大模型融合的开篇之章​ 探秘云原生后端开发​ 云原生后端是什么​ 云原生后端架构核心要素​ 微服务架构​ 容器化技术​ 服务发现与配置管理​ Kubernetes 编排​ 走进腾讯云大模型知识引擎​ 引擎独特功能与优势​ DeepSeek - R1、V3 两款模型 …

【拒绝算法PUA】LeetCode 2116. 判断一个括号字符串是否有效

目录 系列文章目录 专题总结&#xff1a; C刷题技巧总结&#xff1a; 题目 2116. 判断一个括号字符串是否有效 难度 描述 解题方法1 系列文章目录 专题总结&#xff1a; 【拒绝算法PUA】0x00-位运算【拒绝算法PUA】0x01- 区间比较技巧【拒绝算法PUA】0x02- 区间合并技…

常见中间件漏洞攻略-Tomcat篇

一、 CVE-2017-12615-Tomcat put方法任意文件写入漏洞 第一步&#xff1a;开启靶场 第二步&#xff1a;在首页抓取数据包&#xff0c;并发送到重放器 第三步&#xff1a;先上传尝试一个1.txt进行测试 第四步&#xff1a;上传后门程序 第五步&#xff1a;使用哥斯拉连接 二、后…