当前位置: 首页 > news >正文

Linux线程 --- 生产者消费者模型(C语言)

在学习完线程相关的概念之后,本节来认识一下Linux多线程相关的一个重要模型----“ 生产者消费者模型”

本文参考:

Linux多线程生产者与消费者_红娃子的博客-CSDN博客

Linux多线程——生产者消费者模型_linux多线程生产者与消费者_两片空白的博客-CSDN博客

数据结构“入门”—队列(C语言实现)_队列c语言_Fan~Fan的博客-CSDN博客 

生产者消费者模式保姆级教程 (阻塞队列解除耦合性) 一文帮你从C语言版本到C++ 版本, 从理论到实现 (一文足以)_阻塞队列实现生产者消费者模式_小杰312的博客-CSDN博客

生产者与消费者的概念

这个模型的答题逻辑可以使用信号量(POSIX信号量)互斥量+条件变量 实现,这里介绍使用互斥量+条件变量的方法。

 一个进程中的线程有两种角色,一种是生产者,一种是消费者。生产者为消费者提供任务,消费者拿到任务,解决任务。

在生成者和消费者之间还有一个"交易场所",是一个内存块。生成者线程将任务放到内存块中,消费者线程在内存块中拿任务。当内存块数据达到一高水位线时,生产者会进行等待,唤醒消费者拿任务,当内存块数据达到一低水位线时,消费者会等待,并且唤醒生产者生产任务。(条件变量)通过这个模型,可以解除生产者和消费者的强耦合问题。

生成者,消费者存在着3种关系。生产者和生产者之间是互斥的关系消费者和消费者之间是互斥的关系生产者和消费者之间是互斥和同步的关系

对于生产者:

对于消费者:

 

关键的问题,在于生产者和消费者什么时候睡眠,又什么时候被唤醒从哪里读取和写入,这就是生产者和消费者模型的关键

什么时候睡眠和唤醒在上图已经演示,从哪里读取和写入的答案应该是“队列”。

所以生产者和消费者不直接相互通信,而是通过队列,队列就是这个模型可以解耦的关键。

C语言的队列 

既然要学习队列,就要先学习C语言的队列相关知识:

队列的概念

只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出(FIFO)的属性。入队是从队尾添加数据,出队是从队头读取数据。

队列的实现 

队列的实现可以使用数组或者是链表结构,相对而言链表的结构更优一些。

 

使用阻塞队列来实现生产者消费者的模型

在多线程编程中,阻塞队列是一种常用于实现生产者和消费者模型的数据结构。其普通队列区别在于,当队列为空时,从队列获取元素的操作将会被阻塞,直到队列中被放入元素当队列满的时候,往队列中存放元素的操作也会被阻塞,直到有元素从队列中取出

队列的形式并不重要,这里采用环形队列:

实现思路

生产者和生产者之间互斥,消费者和消费者之间互斥

  • 在生产和消费的时候需要定义两个互斥量,一个是生产者之间的,一个是消费者之间的。

生产者和消费者之间互斥且同步

  • 定义一个互斥量,取数据的时候,不能放,放数据的时候,不能取
  • 有两个条件,满和空,定义两个条件变量

代码展示(认真看注释!!

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <signal.h>//定义阻塞队列
typedef  struct BlockQueue { //使用了typedef给结构体起了一个别名“BlockQueue”size_t cap;//容量size_t size;//当前产品个数int front;//队头游标int tail;//队尾游标int* data; //数据域,创建了一个数据类型为int的数组,data指向数组头的地址pthread_mutex_t lock;pthread_cond_t full;pthread_cond_t free;
} BlockQueue;BlockQueue* bqp;//定义全局方便信号处理时候销毁 
//如果没有使用typedef,此处就应该为“struct BlockQueue *bqp;”
//此处定义指针的原因是,接下来有很多函数会修改结构体的参数,如果直接传结构体作为形参,那么修改的就是局部变量,只有传入指向结构体的指针才能方便的直接在函数内修改结构体参数void DestroyBlockQueue(BlockQueue* bqp) { //销毁队列free(bqp->data); //释放分配给指针的空间,防止资源无效占用pthread_mutex_destroy(&bqp->lock);pthread_cond_destroy(&bqp->full);pthread_cond_destroy(&bqp->free);
}void handler(int signo) { //自定义的信号处理函数,详见main的signal函数printf("ByeBye\n");DestroyBlockQueue(bqp);exit(EXIT_SUCCESS);
}BlockQueue* InitQueue(int n) { //初始化阻塞队列BlockQueue* bqp = (BlockQueue*)malloc(sizeof(BlockQueue)); //使用malloc分配空间bqp->cap = n; //容量为nbqp->size = 0; //当前产品个数为0bqp->front = bqp->tail = 0; //由于现在没有产品,所以队头和队尾的游标都是0bqp->data = (int*)malloc(sizeof(int) * n); //给指向数据的指针分配空间,大小是“容量” 乘以 “int型变量大小”pthread_mutex_init(&bqp->lock, NULL); //初始化互斥量pthread_cond_init(&bqp->free, NULL); //初始化代表“队列为空”的条件变量pthread_cond_init(&bqp->full, NULL);//初始化代表“队列已满”的条件变量return bqp; //返回指向结构体的指针
}int IsEmpty(BlockQueue* bqp) {//判断阻塞队列是否为空的函数return bqp->size == 0; //返回值如果是1则代表容量是0,队列空;反之代表队列容量不为0,队列非空
}int IsFull(BlockQueue* bqp) {//判断阻塞队列是否已满的函数return bqp->size == bqp->cap; //返回值如果是1则代表当前产品个数=容量,队列满;反之代表队列未满
}void WaitConsume(BlockQueue* bqp) {//消费被阻塞, 此时队列为空,等待队列有产品pthread_cond_wait(&bqp->full, &bqp->lock);
}void WaitProduct(BlockQueue* bqp) {//生产被阻塞, 此时队列已满,等待队列有空位pthread_cond_wait(&bqp->free, &bqp->lock);
}void NotifyConsume(BlockQueue* bqp) {//通知消费, 队列中有产品了pthread_cond_signal(&bqp->full);
}void NotifyProduct(BlockQueue* bqp) {//通知生产, 队列中有空位了pthread_cond_signal(&bqp->free);
}void Lock(BlockQueue* bqp) { //上锁pthread_mutex_lock(&bqp->lock);
}void Unlock(BlockQueue* bqp) { //解锁pthread_mutex_unlock(&bqp->lock);}void Push(BlockQueue* bqp, int val) { //向队列中增加数据的函数,即生产的函数Lock(bqp);//上锁while (IsFull(bqp)) { //当队列已满的时候,不断执行以下代码,直到队列有空位出现WaitProduct(bqp);//生产被阻塞, 此时队列已满,等待队列有空位NotifyConsume(bqp);//不断催促消费,这样才可以使得队列有空位从而跳出循环}bqp->data[bqp->tail++] = val;//在data数组的尾部增加一个元素,并把队尾游标加一bqp->tail %= bqp->cap;//bqp->tail =  bqp->tail % bqp->cap,如果队尾的游标大小没到容量大小就保持不变,超出则取余//目的就是让队尾游标数值在超出容量数值的时候归0重新覆盖写//Unlock(bqp);//解锁bqp->size += 1;//当前产品数量加一NotifyConsume(bqp);//有产品了通知消费Unlock(bqp);//解锁
}void Pop(BlockQueue* bqp, int* popval) { //从队列中取出数据的函数,即消费的函数Lock(bqp);//上锁while (IsEmpty(bqp)) { //当队列为空的时候,不断执行以下代码,直到队列不为空WaitConsume(bqp);//消费被阻塞, 此时队列为空,等待队列有产品NotifyProduct(bqp);//不断催促生产,这样才可以使得队列有产品(非空)从而跳出循环}*popval = bqp->data[bqp->front++];//从data数组的头部读取一个消息,并把队头游标加一bqp->front %= bqp->cap; //bqp->front =  bqp->front % bqp->cap,如果队头的游标大小没到容量大小就保持不变,超出则取余//目的就是让队头游标数值在超出容量数值的时候归0从头重新读//Unlock(bqp);//解锁bqp->size -= 1;//当前产品数量减一NotifyProduct(bqp);//有空位了通知生产Unlock(bqp);//解锁
}void* ConsumeRoutine(void* args) {//消费者线程执行函数,所有消费者共用这个函数BlockQueue* bqp = (BlockQueue*)args; //此时的线程参数是一个包装好的结构体,在代码头已定义int popval = 0;for ( ;; ) { //相当于一个while(1)Pop(bqp, &popval);//消费的函数,消费一个队头的数据printf("PopVal is %d, and has %ld Products\n", popval, bqp->size); //bqp结构体中的size成员的类型是size_t,在系统中对size_t的定义是无符号长整形,要用%ld表示sleep(rand() % 3);//rand() % 3代表随机取一个0~2的整数,即随机睡眠0~2秒,,随机数种子在main中定义}return (void*)0;
}void* ProductRoutine(void* args) {//生产者线程执行函数,所有生产者共用这个函数BlockQueue* bqp = (BlockQueue*)args;int pushval = 0;for ( ;;  ) { //相当于一个while(1)pushval = rand() % 1024;//准备放入队列的数据(产品), 是一个0~1023的随机整数,随机数种子在main中定义Push(bqp, pushval);//生产的函数,将一个产品塞入队尾(生产一个产品)printf("PushVal is %d, and has %ld Products\n", pushval, bqp->size); //bqp结构体中的size成员的类型是size_t,在系统中对size_t的定义是无符号长整形,要用%ld表示sleep(rand() % 3); //rand() % 3代表随机取一个0~2的整数,即随机睡眠0~2秒,,随机数种子在main中定义}return (void*)0;
}int main() {signal(SIGINT, handler);//当键盘输入“CTRL+C”时,触发SIGINT信号,跳转到自定义的handler函数(信号相关概念)srand((unsigned int)time(NULL)); //使用“(unsigned int)time(NULL)”作为生成随机数的种子bqp = InitQueue(30); //初始化并赋值给结构体bqp,设定容量为30pthread_t consume1, consume2, product1, product2; //定义并创建4个线程pthread_create(&product1, NULL, ProductRoutine, (void*)bqp);//2个生产者使用生产者共用函数作为启动函数pthread_create(&product2, NULL, ProductRoutine, (void*)bqp);pthread_create(&consume1, NULL, ConsumeRoutine, (void*)bqp);//2个消费者使用消费者共用函数作为启动函数pthread_create(&consume2, NULL, ConsumeRoutine, (void*)bqp);pthread_join(product1, NULL);//4个线程等待退出pthread_join(product2, NULL);pthread_join(consume1, NULL);pthread_join(consume2, NULL);return 0;
}

运行效果:

相关文章:

Linux线程 --- 生产者消费者模型(C语言)

在学习完线程相关的概念之后&#xff0c;本节来认识一下Linux多线程相关的一个重要模型----“ 生产者消费者模型” 本文参考&#xff1a; Linux多线程生产者与消费者_红娃子的博客-CSDN博客 Linux多线程——生产者消费者模型_linux多线程生产者与消费者_两片空白的博客-CSDN博客…...

Vue2向Vue3过度核心技术computed计算属性

目录 1 computed计算属性1.1 概念1.2 语法1.3 注意1.4.案例1.5.代码准备 2 computed计算属性 VS methods方法2.1 computed计算属性2.2 methods计算属性2.3 计算属性的优势2.4 总结 3 计算属性的完整写法 1 computed计算属性 1.1 概念 基于现有的数据&#xff0c;计算出来的新属…...

芯片行业震荡期,数字后端还可以入吗?

自去年开始&#xff0c;芯片行业仿佛进入了动荡期&#xff0c;经历了去年秋招和今年春招的小伙伴都知道&#xff0c;如今找工作有多难。 半导体行业人才缩减、各大厂裁员&#xff0c;在加上高校毕业生人数破千万&#xff0c;对于即将踏入IC这个行业的应届生来说&#xff0c;今…...

“精准时空”赋能制造业智能化发展

作者&#xff1a;邓中亮 高达动态厘米级的高精度定位服务&#xff0c;不仅是北斗卫星导航系统的一大独门绝技&#xff0c;其在产业化应用层面也已逐步向普适化、标配化演进&#xff0c;并延展出时空智能新兴产业。 5月17日&#xff0c;当长征三号乙运载火箭成功发射北斗系统的…...

Kotlin协程flow发送时间间隔debounce

Kotlin协程flow发送时间间隔debounce debounce的作用是让连续发射的数据之间间隔起来。典型的应用场景是搜索引擎里面的关键词输入&#xff0c;当用户输入字符时候&#xff0c;有时候&#xff0c;并不希望用户每输入任何一个单字就触发一次后台真正的查询&#xff0c;而是希望…...

ServiceManager接收APP的跨进程Binder通信流程分析

现在一起来分析Server端接收&#xff08;来自APP端&#xff09;Binder数据的整个过程&#xff0c;还是以ServiceManager这个Server为例进行分析,这是一个至下而上的分析过程。 在分析之前先思考ServiceManager是什么&#xff1f;它其实是一个独立的进程&#xff0c;由init解析i…...

Git问题:解决“ssh:connect to host github.com port 22: Connection timed out”

操作系统 Windows11 使用Git IDEA 连接方式&#xff1a;SSH 今天上传代码出现如下报错&#xff1a;ssh:connect to host github.com port 22: Connection timed out 再多尝试几次&#xff0c;依然是这样。 解决 最终发现两个解决方案&#xff1a;&#xff08;二选一&#xf…...

在Eclipse中创建javaweb工程

新建动态web工程 点击project或other之后&#xff0c;如何快速找到Dynamic Web Project 填写工程名等详细信息 也许会出现下面的对话框 项目结构图...

Pycharm链接远程mysql报错

Pycharm链接远程mysql配置及相应报错如下&#xff1a; 解决方法&#xff1a; 去服务器确认Mysql版本号&#xff1a; 我的Mysql为5.7.43&#xff0c;此时Pycharm mysql驱动为8.0版本&#xff0c;不匹配&#xff0c;所以需要根据实际的版本选择对应的驱动&#xff1b;选择对应的版…...

【硕士论文完美复现】【价格型需求响应】基于需求侧响应的配电网供电能力综合评估(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

Android Okhttp 源码浅析三

核心方法 getResponseWithInterceptorChain() internal fun getResponseWithInterceptorChain(): Response {// Build a full stack of interceptors.val interceptors mutableListOf<Interceptor>()interceptors client.interceptorsinterceptors RetryAndFollowUpI…...

一分钟学会用pygame制作棋盘背景

一分钟一个Pygame案例&#xff0c;这一集我们来学习一下如何生成一个视频中的棋盘背景效果&#xff0c;非常非常简单。 视频教程链接&#xff1a;https://www.bilibili.com/video/BV17G411d7Ah/ 当然我们这里是用来做页面的背景&#xff0c;你也可以拿来做别的效果&#xff0…...

Java --- 包装类

一、包装类 Java针对八种基本数据类型定义了相应的引用类型&#xff1a;包装类&#xff08;封装类&#xff09;。 二、基本数据类型与包装类的基本转换 public class WrapperTest {public static void main(String[] args) {//基本数据类型转换为包装类Boolean aBoolean new…...

[运维] wvp 28181安装部署全流程(ubuntu2204)

部署wvp 系统环境 系统版本&#xff1a;ubuntu2204 安装相关工具 sudo apt update ## 编译工具 sudo apt install git openjdk-11-jdk tar vim cmake gcc g libsrtp2-dev libssl-dev ## ffmepg sudo apt install ffmpeg编译zlm 编译zlm git clone https://gitee.com/xia-…...

vue实现富文本

效果图展示 一、安装依赖 npm install vue-quill-editor --save二、具体使用 html <template><!-- 富文本 --><quill-editorref"myQuillEditor"v-model"content":options"editorOption"blur"onEditorBlur($event)"…...

uniapp 开发微信小程序使用echart的dataZoom属性缩放功能不生效!bug记录!

在本项目中使用的是这个echart库 在项目中添加了dataZoom配置项但是不生效&#xff0c;突然想到微信小程序代码大小的限制&#xff0c;之前的echarts.js是定制的&#xff0c;有可能没有加dataZoom组件。故重新定制echarts.js。之前用的echarts版本是5.0.0&#xff0c;这次也是…...

用户端Web自动化测试_L4

目录&#xff1a; selenium多浏览器处理执行 javascript 脚本headless无头浏览器使用capability配置参数解析企业微信实战cypress测试框架介绍Playwright测试框架介绍 1.selenium多浏览器处理 多浏览器测试背景 用户使用的浏览器(firefox,chrome,IE 等)web 应用应该能在任何…...

CAPL - Panel和TestModule结合实现测试项可选

目录 一、定义脚本编号和脚本组编号 1、测试组定义 2、测试脚本编号定义...

机器学习,过拟合与欠拟合,正则化与交叉验证

目录 机器学习 过拟合与欠拟合 正则化与交叉验证 正则化 交叉验证 机器学习 的目的是使学到的模型不仅对已知数据而且对未知数据都能有很好的预测能力。 不同的机器学习方法会给出不同的模型。当损失函数给定时&#xff0c;基于损失函数的模型的训练误差&#xff08;tra…...

gradio使用transformer模块demo介绍1:Text Natural Language Processing

文章目录 文本生成 Text Generation自动完成 Autocomplete情感分析 Sentiment Analysis命名实体识别 Name Entity Recognition NER多语种翻译文本生成 Text Generation import gradio as gr from transformers import pipelinegenerator = pipeline(text-generation, model=&l…...

算法通关村——数论经典问题解析

1. 辗转相除法 主要目的是获取两个数里面的最大公约数。 public int gcd(int a, int b) {int k 0;do {k a % b;a b;b k;} while (k ! 0);return a;}2. 素数和合数 素数的要求是必须大于等于2&#xff0c;并且只能被1和它本身整除。 判断的方法比较简单&#xff0c;就是从…...

代码随想录算法训练营第四十六天|LeetCode 1143,1035,53

目录 LeetCode 1143.最长公共子序列 动态规划五步曲&#xff1a; 1.确定dp[i][j]的含义 2.找出递推公式 3.初始化dp数组 4.确定遍历顺序 5.打印dp数组 LeetCode 1035.不相交的线 LeetCode 53.最大子序列和&#xff08;动态规划&#xff09; 动态规划五步曲&#xff1a; 1.确定…...

leetcode 541.反转字符串II

⭐️ 题目描述 &#x1f31f; leetcode链接&#xff1a;https://leetcode.cn/problems/reverse-string-ii/ ps&#xff1a; 这道题描述的有点晦涩难懂&#xff0c;意思就是每隔k个反转k个&#xff0c;末尾不够k个时全部反转&#xff0c;开始就不够k个也全部反转。 代码&#…...

MyBatis与Spring整合以及AOP和PageHelper分页插件整合

目录 前言 一、MyBatis与Spring整合的好处以及两者之间的关系 1.好处 2.关系 二、MyBatis和Spring集成 1.导入pom.xml 2.编写配置文件 3.利用mybatis逆向工程生成模型层代码 三、常用注解 四、AOP整合pageHelper分页插件 创建一个切面 测试 前言 MyBatis是一个开源的…...

《认知觉醒》读书笔记之潜意识

模糊--人生是一场消除模糊的比赛。 学习知识&#xff0c;消除认知模糊 掌握的工具越多&#xff0c;认知能力越强&#xff0c;消除模糊的能力就越强。 元认知-----》 如何反观自己。 刻意练习----》 如何精进自己。 运动改造大脑---》 如何激化自己的运动热情。 学习知识的…...

Stable Diffusion 系列教程 | 图生图基础

前段时间有一个风靡全网的真人转漫画风格&#xff0c;受到了大家的喜欢 而在SD里&#xff0c;就可以通过图生图来实现类似的效果 当然图生图还有更好玩的应用&#xff0c;我们一点一点来探索 首先我们来简单进行一下图生图的这一个实践---真人转动漫 1. 图生图基本界面 和…...

cuda编程day001

一、环境&#xff1a; ①、linux cuda-11.3 opecv4.8.0 不知道头文件和库文件路径&#xff0c;用命令查找&#xff1a; # find /usr/local -name cuda.h 2>/dev/null # 查询cuda头文件路径 /usr/local/cuda-11.3/targets/x86_64-linux/include/cuda.h # find /usr/…...

Java 中使用 ES 高级客户端库 RestHighLevelClient 清理百万级规模历史数据

&#x1f389;工作中遇到这样一个需求场景&#xff1a;由于ES数据库中历史数据过多&#xff0c;占用太多的磁盘空间&#xff0c;需要定期地进行清理&#xff0c;在一定程度上可以释放磁盘空间&#xff0c;减轻磁盘空间压力。 &#x1f388;在经过调研之后发现&#xff0c;某服务…...

C++最易读手撸神经网络两隐藏层(任意Nodes每层)梯度下降230821a

// c神经网络手撸20梯度下降22_230820a.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 #include<iostream> #include<vector> #include<iomanip> // setprecision #include<sstream> // getline stof() #include<fstream…...

Leetcode 2235.两整数相加

一、两整数相加 给你两个整数 num1 和 num2&#xff0c;返回这两个整数的和。 示例 1&#xff1a; 输入&#xff1a;num1 12, num2 5 输出&#xff1a;17 解释&#xff1a;num1 是 12&#xff0c;num2 是 5 &#xff0c;它们的和是 12 5 17 &#xff0c;因此返回 17 。示例…...

Postman —— postman实现参数化

什么时候会用到参数化 比如&#xff1a;一个模块要用多组不同数据进行测试 验证业务的正确性 Login模块&#xff1a;正确的用户名&#xff0c;密码 成功&#xff1b;错误的用户名&#xff0c;正确的密码 失败 postman实现参数化 在实际的接口测试中&#xff0c;部分参数每…...

LeetCode--HOT100题(41)

目录 题目描述&#xff1a;102. 二叉树的层序遍历&#xff08;中等&#xff09;题目接口解题思路代码 PS: 题目描述&#xff1a;102. 二叉树的层序遍历&#xff08;中等&#xff09; 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&am…...

微信小程序教学系列(6)

第六章&#xff1a;小程序商业化 第一节&#xff1a;小程序的商业模式 在这一节中&#xff0c;我们将探讨微信小程序的商业模式&#xff0c;让你了解如何将你的小程序变成一个赚钱的机器&#xff01; 1. 广告收入 小程序的商业模式之一是通过广告收入赚钱。你可以在小程序中…...

小程序中的全局配置以及常用的配置项(window,tabBar)

全局配置文件和常用的配置项 app.json: pages:是一个数组&#xff0c;用于记录当前小程序所有页面的存放路径&#xff0c;可以通过它来创建页面 window:全局设置小程序窗口的外观(导航栏&#xff0c;背景&#xff0c;页面的主体) tabBar:设置小程序底部的 tabBar效果 style:是否…...

数据工厂调研及结果展示

数据工厂 一、背景 在开发自测、测试迭代测试、产品验收的过程中&#xff0c;都需要各种各样的前置数据&#xff0c;大致分为如下几类&#xff1a; 账号&#xff08;实名、权益等级、注册等&#xff09; 货源&#xff08;优货、急走、相似、一手、普通货源等&#xff09; …...

抓包相关,抓包学习

检查网络流量 - 提琴手经典 (telerik.com) Headers Reference - Fiddler Classic (telerik.com) 以上是fiddler官方文档 F12要勾选保留日志 不勾选的话跳转到新页面之前页面的日志不会在下方显示 会保留所有抓到的包 如果重定向到别的页面 F12抓包可能看不到响应信息,但是…...

云原生之使用Docker部署SSCMS内容管理系统

云原生之使用Docker部署SSCMS内容管理系统 一、SSCMS介绍二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、下载SSCMS镜像五、部署SSCMS内容管理系统5.1 创建SSCMS容器5.2 检查SSC…...

uniapp -- 在组件中拿到pages.json下pages设置navigationBarTitleText这个值?

1:在 pages.json 文件中设置 navigationBarTitleText,例如: {"pages": [{"path": "pages/home/index","style": {"navigationBarTitleText": "首页",&...

Java获取环境变量和运行时环境信息和自定义配置信息

System.getenv() 获取系统环境变量 public static void main1() {Map<String, String> envMap System.getenv();envMap.entrySet().forEach(x-> System.out.println(x.getKey() "" x.getValue())); } System.getenv() 获取的是操作系统环境变量列表&…...

React入门 组件学习笔记

项目页面以组件形式层层搭起来&#xff0c;组件提高复用性&#xff0c;可维护性 目录 一、函数组件 二、类组件 三、 组件的事件绑定 四、获取事件对象 五、事件绑定传递额外参数 六、组件状态 初始化状态 读取状态 修改状态 七、组件-状态修改counter案例 八、this问…...

Windows商店引入SUSE Linux Enterprise Server和openSUSE Leap

在上个月的Build 2017开发者大会上&#xff0c;微软宣布将SUSE&#xff0c;Ubuntu和Fedora引入Windows 商店&#xff0c;反应出微软对开放源码社区的更多承诺。 该公司去年以铂金会员身份加入Linux基金会。现在&#xff0c;微软针对内测者的Windows商店已经开始提供 部分Linux发…...

[NLP]深入理解 Megatron-LM

一. 导读 NVIDIA Megatron-LM 是一个基于 PyTorch 的分布式训练框架&#xff0c;用来训练基于Transformer的大型语言模型。Megatron-LM 综合应用了数据并行&#xff08;Data Parallelism&#xff09;&#xff0c;张量并行&#xff08;Tensor Parallelism&#xff09;和流水线并…...

软考高级系统架构设计师系列论文七十八:论软件产品线技术

软考高级系统架构设计师系列论文七十八:论软件产品线技术 一、摘要二、正文三、总结一、摘要 本人作为某软件公司负责人之一,通过对位于几个省的国家甲级、乙级、丙级设计院的考查和了解,我决定采用软件产品线方式开发系列《设计院信息管理平台》产品。该产品线开发主要有如…...

yolov5中添加ShuffleAttention注意力机制

ShuffleAttention注意力机制简介 关于ShuffleAttention注意力机制的原理这里不再详细解释.论文参考如下链接here   yolov5中添加注意力机制 注意力机制分为接收通道数和不接受通道数两种。这次属于接受通道数注意力机制,这种注意力机制由于有通道数要求,所示我们添加的时候…...

Effective C++条款17——以独立语句将newed 对象置入智能指针(资源管理)

假设我们有个函数用来揭示处理程序的优先权&#xff0c;另一个函数用来在某动态分配所得的widget上进行某些带有优先权的处理: void priority(); void processWidget(std::tr1::shared_ptr<Widget>pw, int priority);由于谨记“以对象管理资源”&#xff08;条款13&…...

奇迹MU服务器如何选择配置?奇迹MU服务器租用

不同的服务器&#xff0c;根据其特点与性能适用于不同的应用场景&#xff0c;为了让你们更好的理解&#xff0c;我们对服务器进行了分类归纳&#xff0c;结合了服务器不同的特点以及价位进行一个区分&#xff0c;帮助我们更好的选择合适的服务器配置。 VPS服务器 VPS服务器又…...

如何远程管理服务器详解

文章目录 前言一、远程管理类型二、远程桌面三、telnet 命令行远程四、查看本地开放端口 前言 很多公司是有自己的机房的&#xff0c;机房里面会有若干个服务器为员工和用户提供服务。大家可以想想&#xff1a;假设这家公司有上百台服务器&#xff0c;我们作为网络工程师&…...

JavaScript——为什么静态方法不能调用非静态方法

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…...

Python实现常见的排序算法

当涉及到排序算法时&#xff0c;一些常见的排序算法包括插入排序、选择排序、冒泡排序、快速排序、归并排序和堆排序。以下是使用Python实现这些常见排序算法的示例代码&#xff1a; 插入排序&#xff08;Insertion Sort&#xff09;&#xff1a; def insertionSort(arr):for…...

【git】fatal: refusing to merge unrelated histories

在一次重新初始化本地仓库后&#xff0c;拉取远程仓库时提示&#xff1a; fatal: refusing to merge unrelated histories 在“fatal: refusing to merge unrelated histories”&#xff08;即&#xff0c;不知道彼此的存在&#xff0c;并已不匹配的项目提交历史&#xff09;…...