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

[多线程]基于环形队列(RingQueue)的生产者-消费者模型的实现

标题:[多线程]基于环形队列(RingQueue)的生产者-消费者模型
@水墨不写bug


在这里插入图片描述


一、模型实现

接下来我们要实现一个基于环形队列(RingQueue)生产者-消费者模型。该模型使用信号量和互斥锁来保证生产者和消费者之间的同步与互斥操作。

#pragma once
#include <iostream>
#include <vector>
#include <pthread.h>
#include <semaphore.h>using std::cout;
using std::endl;// 基于环形队列的生产消费模型
// 与加锁不同,加锁要求对象rq内部内嵌一个锁,而两个信号量
// (sem_t _data_sem;  // 数据信号量
//     sem_t _spase_sem; // 空间信号量)
// 可以做到完美维护以下的四条规则:
/*1.生产者不会套消费者一圈2.消费者不超过生产者3.队列为空,消费者先消费4.队列为满,生产者先生产
*/template <typename T>
class RingQueue
{
private:// 信号量(计数器)自减——申请信号量void P(sem_t &psem){sem_wait(&psem);}// 信号量(计数器)自增——归还信号量void V(sem_t &vsem){sem_post(&vsem);}public:RingQueue(int maxcap): _ringqueue(maxcap), _maxcap(maxcap), _data_sem(), _space_sem(), _p_step(0), _c_step(0), _size(0){   // 初始化信号量sem_init(&_data_sem, 0, 0);sem_init(&_space_sem, 0, maxcap);// 初始化互斥锁pthread_mutex_init(&_p_mutex, nullptr);pthread_mutex_init(&_c_mutex, nullptr);}// 生产者向环形队列插入数据void Push(const T& in){// 申请空间信号量P(_space_sem);pthread_mutex_lock(&_p_mutex);_ringqueue[_p_step] = in;_p_step++;_p_step %= _maxcap;_size++;pthread_mutex_unlock(&_p_mutex);V(_data_sem);}// 消费者从环形队列拿出数据void Pop(T *out){// 申请数据信号量P(_data_sem);pthread_mutex_lock(&_c_mutex);*out = _ringqueue[_c_step];_c_step++;_c_step %= _maxcap;_size--;pthread_mutex_unlock(&_c_mutex);V(_space_sem);}~RingQueue(){// 销毁信号量sem_destroy(&_data_sem);sem_destroy(&_space_sem);}size_t GetSize(){return _size;}private:// 环形队列std::vector<T> _ringqueue;int _maxcap; // 最大数据个数sem_t _data_sem;  // 数据信号量sem_t _space_sem; // 空间信号量pthread_mutex_t _p_mutex; // 维护生产者之间关系的互斥锁pthread_mutex_t _c_mutex; // 维护消费者之间关系的互斥锁int _p_step; // 生产者位置int _c_step; // 消费者位置int _size; // 队列内数据个数
};

二、模型设计详解

1. 成员变量

  • std::vector<T> _ringqueue:环形队列,用于存储数据。
  • int _maxcap:队列的最大容量。
  • sem_t _data_semsem_t _space_sem:信号量,分别用于表示队列中的数据量和剩余空间量。(生产者和消费者关系的资源类型不同;生产者关心剩余空间资源,消费者关心剩余数据资源
  • pthread_mutex_t _p_mutexpthread_mutex_t _c_mutex:互斥锁,分别用于保护生产者和消费者的操作。
  • int _p_stepint _c_step:生产者和消费者在队列中的位置指针。
  • int _size:队列内数据的当前个数。

2. 构造函数

RingQueue(int maxcap): _ringqueue(maxcap), _maxcap(maxcap), _data_sem(), _space_sem(), _p_step(0), _c_step(0), _size(0)
{// 初始化信号量sem_init(&_data_sem, 0, 0);sem_init(&_space_sem, 0, maxcap);// 初始化互斥锁pthread_mutex_init(&_p_mutex, nullptr);pthread_mutex_init(&_c_mutex, nullptr);
}
  • 初始化环形队列的最大容量。
  • 初始化信号量,其中 _data_sem 的初始值为 0,表示初始时没有数据;_space_sem 的初始值为 maxcap,表示初始时队列可用空间为最大容量。
  • 初始化互斥锁 _p_mutex_c_mutex,分别用于维持生产者之间和消费者之间的互斥。

3. Push 函数

void Push(const T& in)
{// 申请空间信号量P(_space_sem);pthread_mutex_lock(&_p_mutex);_ringqueue[_p_step] = in;_p_step++;_p_step %= _maxcap;_size++;pthread_mutex_unlock(&_p_mutex);V(_data_sem);
}
  • P(_space_sem):生产者申请空间信号量,如果队列已满(信号量为0),则生产者阻塞等待。
  • pthread_mutex_lock(&_p_mutex):加锁保护生产者的操作。
  • 将数据插入到环形队列的当前位置 _p_step,然后更新 _p_step_size
  • pthread_mutex_unlock(&_p_mutex):解锁。
  • V(_data_sem):释放数据信号量,通知消费者有新数据可用。

4. Pop 函数

void Pop(T *out)
{// 申请数据信号量P(_data_sem);pthread_mutex_lock(&_c_mutex);*out = _ringqueue[_c_step];_c_step++;_c_step %= _maxcap;_size--;pthread_mutex_unlock(&_c_mutex);V(_space_sem);
}
  • P(_data_sem):消费者申请数据信号量,如果队列为空(信号量为0),则消费者阻塞等待。
  • pthread_mutex_lock(&_c_mutex):加锁保护消费者的操作。
  • 从环形队列的当前位置 _c_step 取出数据,然后更新 _c_step_size
  • pthread_mutex_unlock(&_c_mutex):解锁。
  • V(_space_sem):释放空间信号量,通知生产者有新的可用空间。

5. 析构函数

~RingQueue()
{// 销毁信号量sem_destroy(&_data_sem);sem_destroy(&_space_sem);
}
  • 销毁信号量,释放资源。

6. GetSize 函数

size_t GetSize()
{return _size;
}
  • 返回队列的当前大小。

三、模型总结

上述代码实现了一个基于环形队列的生产者-消费者模型,通过使用信号量来控制生产者和消费者之间的同步和互斥,通过互斥锁来保证生产者之间消费者之间的互斥。
信号量用于控制队列中的数据量和剩余空间量,互斥锁用于保护生产者和消费者的操作。通过这种方式,可以有效地避免资源竞争和死锁问题,实现了高效的生产和消费操作。

四、模型测试

以下给出了模型的测试逻辑代码,可以清晰的观察出单生产单消费,多生产多消费的情况:

#include "RingQueue.hpp"
#include <unistd.h>
#include <cstdlib>
void *Product(void *args)
{RingQueue<int> *rq = static_cast<RingQueue<int> *>(args);while (true){// 1.生产数据int tem = (rand() ^ pthread_self()) % 37;// 2.加入环形队列(访问临界资源)rq->Push(tem);cout << "Product num : " << tem << endl;sleep(1);// usleep(100000);}return nullptr;
}void *Consume(void *args)
{RingQueue<int> *rq = static_cast<RingQueue<int> *>(args);while (true){// 1.拿到数据(访问临界资源)int get;rq->Pop(&get);// 2.处理数据cout << "Consumer get :" << get << endl;//usleep(110000);}return nullptr;
}void test1()
{cout << "main thread started ---pid:" << getpid() << endl;srand((unsigned int)time(nullptr));RingQueue<int> *rq = new RingQueue<int>(10);// 创建线程pthread_t p, c;pthread_create(&p, nullptr, Product, (void *)rq);pthread_create(&c, nullptr, Consume, (void *)rq);while (1){cout << "队列内数据个数:" << rq->GetSize() << endl;sleep(1);}// 等待线程pthread_join(p, nullptr);pthread_join(c, nullptr);
}
void test2()
{cout << "main thread started ---pid:" << getpid() << endl;srand((unsigned int)time(nullptr));RingQueue<int> *rq = new RingQueue<int>(10);// 创建多个生产者消费者pthread_t p1, c1;pthread_t p2, c2;pthread_t p3, c3;pthread_t p4, c4;pthread_create(&p1, nullptr, Product, (void *)rq);pthread_create(&p2, nullptr, Product, (void *)rq);pthread_create(&p3, nullptr, Product, (void *)rq);pthread_create(&p4, nullptr, Product, (void *)rq);pthread_create(&c1, nullptr, Consume, (void *)rq);pthread_create(&c2, nullptr, Consume, (void *)rq);pthread_create(&c3, nullptr, Consume, (void *)rq);pthread_create(&c4, nullptr, Consume, (void *)rq);while (1){cout << "队列内数据个数:" << rq->GetSize() << endl;sleep(1);}// 等待线程pthread_join(p1, nullptr);pthread_join(p2, nullptr);pthread_join(p3, nullptr);pthread_join(p4, nullptr);pthread_join(c1, nullptr);pthread_join(c2, nullptr);pthread_join(c3, nullptr);pthread_join(c4, nullptr);
}int main()
{// 测试单生产单消费//  test1();// 测试多生产多消费test2();return 0;
}

完~
转载请注明出处


在这里插入图片描述

相关文章:

[多线程]基于环形队列(RingQueue)的生产者-消费者模型的实现

标题&#xff1a;[多线程]基于环形队列&#xff08;RingQueue&#xff09;的生产者-消费者模型 水墨不写bug 一、模型实现 接下来我们要实现一个基于环形队列&#xff08;RingQueue&#xff09;的生产者-消费者模型。该模型使用信号量和互斥锁来保证生产者和消费者之间的同步与…...

HAL库STM32常用外设—— CAN通信(一)

文章目录 一、CAN是什么&#xff1f;1.1 CAN应用场景1.2 CAN通信优势 二、CAN基础知识介绍2.1 CAN总线结构2.2 CAN总线特点2.2.1 CAN总线的数据传输特点2.2.2 位时序和波特率 2.3 CAN位时序和波特率2.3 CAN物理层2.3.1 CAN 物理层特性2.3.2 CAN 收发器芯片介绍 2.4 CAN协议层2.…...

分页查询的实现

目录 前言 一.问题描述 二.后端实现步骤 2.1配置PageHelper插件 ①导入依赖 ②在application.yml配置文件中添加相关配置 2.2编写一个入门的程序&#xff0c;体验分页过程 2.3定义一个vo&#xff0c;用来收集分页后的所有信息 2.4修改serviceImpl层的代码 2.5动态设…...

Sourcetree——使用.gitignore忽略文件或者文件夹

一、为何需要文件忽略机制&#xff1f; 1.1 为什么要会略&#xff1f; 对于开发者而言&#xff0c;明智地选择忽略某些文件类型&#xff0c;能带来三大核心优势&#xff1a; 仓库纯净性&#xff1a;避免二进制文件、编译产物等污染代码库 安全防护&#xff1a;防止敏感信息&…...

Thinkphp的belongsToMany(多对多) 和 hasManyThrough(远程一对多)的区别是什么?

虽然 belongsToMany&#xff08;多对多&#xff09; 和 hasManyThrough&#xff08;远程一对多&#xff09; 都会使用 JOIN 查询&#xff0c;但它们的核心区别在于 关联关系的本质不同&#xff0c;具体如下&#xff1a; 1️⃣ belongsToMany&#xff08;多对多&#xff09; &a…...

DataWhale 大语言模型 - 大模型技术基础

本课程围绕中国人民大学高瓴人工智能学院赵鑫教授团队出品的《大语言模型》书籍展开&#xff0c;覆盖大语言模型训练与使用的全流程&#xff0c;从预训练到微调与对齐&#xff0c;从使用技术到评测应用&#xff0c;帮助学员全面掌握大语言模型的核心技术。并且&#xff0c;课程…...

Docker+Flask 实战:打造高并发微服务架构

DockerFlask 实战&#xff1a;打造高并发微服务架构 今天我们要深入探讨一个非常热门且实用的主题&#xff1a;基于 Docker 部署 Python Flask 应用。Docker 作为当下最流行的容器化技术&#xff0c;已经广泛应用于各种开发和部署场景&#xff0c;尤其是在微服务架构中。而 Fl…...

前端跨域如何调试,以及相关概念梳理【环境变量 本地代理 正向代理 反向代理 OPTIONS请求 CDN 等】

跨域报错 一 前端日常开发时&#xff0c;项目的部署地址和接口请求的地址一般是同源的&#xff0c;不会跨域。 例如项目的测试环境部署在https://my-dev.BeatingWorldLine.com/xxx, 测试环境的访问接口域名也要相同来保证不跨域https://my-dev.BeatingWorldLine.com/api/xxx, …...

【区块链】以太坊

学习视频源链接&#xff1a; https://www.bilibili.com/video/BV1Vt411X7JF/ 本文是根据肖老师的视频进行的笔记记录 bitcoin 1.0 区块链 以太坊 2.0区块链 以太坊 设置了 memory hard mining puzzle &#xff0c;这造成了asic resistance&#xff0c; 后续 proof of work &a…...

MCU的工作原理:嵌入式系统的控制核心

MCU的工作原理可以概括为以下几个步骤&#xff1a; 1. 初始化 上电后&#xff0c;MCU从Flash存储器中加载程序代码&#xff0c;并初始化外设和寄存器。 2. 任务执行 根据程序逻辑&#xff0c;MCU执行数据处理、外设控制和通信等任务。通过中断系统实时响应外部事件。 3. 低…...

离线服务器ollama新增qwen2:0.5b模型

离线服务器ollama新增qwen2:0.5b模型 Dify集成ollama前面已经介绍过离线服务器CentOS使用的docker安装的ollama&#xff0c;其中在ollama中已经安装了deepseek-r1:1.5b。目前的需求是需要再安装一个qwen2:0.5b的模型&#xff0c;那么如何安装呢&#xff1f; 1.首先在有网的服…...

Ubuntu20.04安装运行DynaSLAM

目录 一、安装Anaconda 二、相关依赖库安装 1、boost安装 2、Eigen 3安装 3、opencv安装 4、Pangolin安装 三、配置Mask_RCNN环境 四、DynaSLAM编译 五、DynaSLAM运行 一、安装Anaconda 打开以下链接&#xff1a; Index of / 下载和自己系统匹配的安装包。这里下…...

Apache Shiro反序列化漏洞深度剖析:从原理到利用

引言 在Web安全的世界里&#xff0c;反序列化漏洞一直是最危险的漏洞类型之一。今天&#xff0c;我们将深入探讨Apache Shiro框架中的两个著名反序列化漏洞.通过通俗易懂的解释和详细的实例&#xff0c;帮助你理解这类漏洞的本质和危害。 Shiro框架与"记住我"功能简…...

Android UI 组件系列(二):Button 进阶用法

引言 在上一篇博客中&#xff0c;我们介绍了 Button 的基本用法和常见属性&#xff0c;掌握了 Button 的基础知识。然而&#xff0c;在实际开发中&#xff0c;Button 远不止于简单的点击功能&#xff0c;它还可以支持不同的变体、丰富的自定义样式&#xff0c;以及更灵活的状态…...

CentOS-7安装Docker(更新时间:2025-03-12)

CentOS-7安装Docker 该文章记录在CentOS 7上安装Docker的过程和步骤&#xff0c;以及在安装过程中遇到的困难和解决方案。 目录 CentOS-7安装Docker一、环境准备二、安装Docker1.验证服务器是否接入互联网2. 检查CentOS内核版本3.使用root权限登录CentOS。确保yum包更新到最新…...

网络空间安全(31)安全巡检

一、定义与目的 定义&#xff1a; 安全巡检是指由专业人员或特定部门负责&#xff0c;对各类设施、设备、环境等进行全面或重点检查&#xff0c;及时发现潜在的安全隐患或问题。 目的&#xff1a; 预防事故发生&#xff1a;通过定期的安全巡检&#xff0c;及时发现并解决潜在的…...

Kubernetes学习笔记-移除Nacos迁移至K8s

项目服务的配置管理和服务注册发现由原先的Nacos全面迁移到Kubernetes上。 一、移除Nacos 移除Nacos组件依赖。 <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <…...

Docker 构建 nginx-redis-alpine 项目详解

Docker 构建 nginx-redis-alpine 项目详解 一、课程概述 嘿&#xff0c;朋友们&#xff01;今天咱们要深入探索一个超级实用的项目 ——nginx-redis-alpine&#xff01;这个项目可不简单&#xff0c;它包含了好多重要的知识点&#xff0c;像文件目录结构、核心文件的作用及配…...

【教学类-43-26】20240312 数独4宫格的所有可能(图片版 576套样式,空1格-空8格,每套65534张*576小图=3千万张小图)

背景需求&#xff1a; 之前做了三宫格所有可能图片 510小图*12套6120图&#xff0c;所以3分钟就生成了 【教学类-43-25】20240311 数独3宫格的所有可能&#xff08;图片版 12套样式&#xff0c;空1格-空8格&#xff0c;每套510张&#xff0c;共6120小图&#xff09;-CSDN博客…...

ChromeOS 134 版本更新

ChromeOS 134 版本更新 一、ChromeOS 134 更新内容 1. ChromeOS 自助终端&#xff08;Kiosk&#xff09;模式支持隔离 Web 应用&#xff08;Isolated Web Apps&#xff09; 从 ChromeOS 134 开始&#xff0c;自助终端&#xff08;Kiosk&#xff09;模式支持 隔离 Web 应用&a…...

Redis面试篇

目录 Redis面试篇 1.什么是Redis&#xff1f;作用是什么&#xff1f; 2.什么是缓存穿透、缓存击穿、缓存雪崩 2.1缓存穿透 2.2缓存击穿 2.3缓存雪崩 3.redis如何持久化 1. RDB&#xff08;快照存储&#xff09; 2. AOF&#xff08;追加日志&#xff09; 4.Redis 的过…...

C#中通过Response.Headers设置自定义参数

一、基础设置方法 1. 直接添加自定义头 // ASP.NET Core方案 Response.Headers.Append("X-API-Version", "2.3.1"); Response.Headers.Append("Custom-Auth-Token", Guid.NewGuid().ToString());• 底层原理&#xff1a;通过IHeaderDictionary…...

C++标准模板库学习--函数模板返回值参数类型

template<typename T1, typename T2> 2 T1 max (T1 a, T2 b) 3 { 4 return b < a ? a : b; 5 } 6 ... 7 auto m ::max(4, 7.2); // OK, 不过返回类型与第一个参数类型一样 如何解决模板的返回类型 法一&#xff0c;使用decltype进行类型推断&#xff0c;在编译时…...

BUG修复 | 一次钉钉工作台应用远程调试实战(开发者工具)

#1 ℹ️背景故事 最近用户反馈&#xff0c;钉钉工作台的应用无法正常使用&#xff0c;卡在自动登录页面。 天&#xff0c;这是运行10年的老程序&#x1f631;&#xff0c;我当时真是吓得不轻。这老古董完全不记得怎么改了&#x1f602;。 #2 &#x1f41e;开启远程调试 钉钉…...

[目标检测] 训练之前要做什么

背景&#xff1a;训练一个Yolo8模型&#xff0c;在训练之前&#xff0c;数据集的处理是影响效果的关键因素。 Step1 定义规则 什么是人/车&#xff0c;比如人的话可能是站着的人&#xff0c;如果是骑电动车/自行车就不算是人。 Step2 收集数据集 1. 自己标注。如果是自己标…...

一窥DeepSeek开源EPLB项目:揭开技术背后的面纱

摘要 在DeepSeek开源DualPipe项目的同一天&#xff0c;EPLB项目也正式对外公开。EPLB&#xff08;Enhanced Pipeline Balancing&#xff09;并非一蹴而就的奇迹&#xff0c;而是经过长时间的研发与优化。该项目旨在通过改进管道平衡机制&#xff0c;提升系统的稳定性和效率。本…...

达梦数据库中插入导出图片的方法与应用

达梦数据库中插入导出图片的方法与应用 在数据库的实际应用场景中&#xff0c;图片存储是一项常见且重要的需求。以电商平台为例&#xff0c;商品展示图片是吸引消费者的关键元素&#xff1b;而在社交软件里&#xff0c;用户头像更是个人形象的直观体现。针对达梦数据库&#…...

问deepseek: OpenFOAM并行分区后,是如何实现ldumatrix矩阵向量乘法计算逻辑的?

在OpenFOAM中&#xff0c;lduMatrix 是用于存储稀疏矩阵的类&#xff0c;支持并行计算。并行分区后&#xff0c;lduMatrix 的矩阵向量乘法通过以下步骤实现&#xff1a; 1. 矩阵分区 分区&#xff1a;将矩阵和向量分配到多个处理器上&#xff0c;每个处理器负责一部分。接口&…...

linux(ubuntu)中Conda、CUDA安装Xinference报错ERROR: Failed to build (llama-cpp-python)

文章目录 一、常规办法二、继续三、继续四、缺少 libgomp库&#xff08;最终解决&#xff09;在 Conda 环境中安装 libgomp 如果符合标题情况 执行的&#xff1a; pip install "xinference[all]"大概率是最终解决的情况。 一、常规办法 llama-cpp-python 依赖 CMak…...

蓝耘携手通义万象 2.1 图生视频:开启创意无限的共享新时代

在科技飞速发展的今天&#xff0c;各种新奇的技术不断涌现&#xff0c;改变着我们的生活和工作方式。蓝耘和通义万象 2.1 图生视频就是其中两项非常厉害的技术。蓝耘就像是一个超级大管家&#xff0c;能把各种资源管理得井井有条&#xff1b;而通义万象 2.1 图生视频则像是一个…...

04 1个路由器配置一个子网的dhcp服务

前言 这是最近一个朋友的 ensp 相关的问题, 这里来大致了解一下 ensp, 计算机网络拓扑 相关基础知识 这里一系列文章, 主要是参照了这位博主的 ensp 专栏 这里 我只是做了一个记录, 自己实际操作了一遍, 增强了一些 自己的理解 当然 这里仅仅是一个 简单的示例, 实际场景…...

Android studio运行报错处理

没装HAXM报错&#xff1a; Intel HAXM 7.6.5 下载 下载链接&#xff1a; https://www.filehorse.com/download-intel-haxm/54766/download/#google_vignette 运行时弹窗提示&#xff1a;Device manager The emulator process for AVD Pixel_3a_API_34_extension_level_7_x86_6…...

【CXX】6.7 SharedPtr<T> — std::shared_ptr<T>

std::shared_ptr 的 Rust 绑定称为 SharedPtr。 限制&#xff1a; SharedPtr 不支持 T 为不透明的 Rust 类型。对于在语言边界上传递不透明 Rust 类型的所有权&#xff0c;应改用 Box&#xff08;C 中的 rust::Box&#xff09;。 示例 // src/main.rsuse std::ops::Deref; …...

NocoBase 本周更新汇总:双因素身份认证(2FA)

原文链接&#xff1a;https://www.nocobase.com/cn/blog/weekly-updates-202503013 汇总一周产品更新日志&#xff0c;最新发布可以前往我们的博客查看。 本周我们发布了 NocoBase 1.6.0 版本&#xff0c;带来集群模式部署、安全策略优化和迁移管理等多项新特性。 NocoBase …...

【Go学习】04-1-Gin框架-路由请求响应参数

【Go学习】04-1-Gin框架 初识框架go流行的web框架GinirisBeegofiber Gin介绍Gin快速入门 路由RESTful API规范请求方法URI静态url路径参数模糊匹配 处理函数分组路由 请求参数GET请求参数普通参数数组参数map参数 POST请求参数表单参数JSON参数 路径参数文件参数 响应字符串方式…...

DataX的python3使用

datax这东西本身是python2写的&#xff0c;这导致python3&#xff0c;就各种语法报错&#xff0c;问题是&#xff0c;现在的工程都是python3搞的&#xff0c;这就很难受.... 网上找到一篇帖子&#xff0c;可以解决这个问题&#xff1a; 原帖&#xff1a;python3执行datax报错…...

部署项目至服务器:响应时间太长,无法访问此页面?

在我们部署项目到服务器上的时候&#xff0c;一顿操作猛如虎&#xff0c;打开页面..... 这里记录一下这种情况是怎么回事。一般就是服务器上的安全组没有放行端口。 因为我是用宝塔进行项目部署的。所以遇到这种情况&#xff0c;要去操作两边&#xff08;宝塔and服务器所属平台…...

Map<String,Object>中Fastjson提取entrys对应的值

今天在处理接口数据时&#xff0c;需要解析出对方传入的json数据&#xff0c;并需要取出其中一个字段的值来判断&#xff0c;记录下我的步骤&#xff0c;提供参考&#xff1a; 1.json数据准备 {"hrOrgUnit": "00000000-0000-0000-0000-000000000000CCE7AED4&q…...

【毕业论文格式】word分页符后的标题段前间距消失

文章目录 【问题描述】 分页符之后的段落开头&#xff0c;明明设置了标题有段前段后间距&#xff0c;但是没有显示间距&#xff1a; 【解决办法】 选中标题&#xff0c;选择边框 3. 选择段前间距&#xff0c;1~31磅的一个数 结果...

Android,Java,Kotlin 确保线程顺序执行的多种实现方式

在多线程编程中&#xff0c;有时需要确保一个线程必须等待另一个线程执行完毕后再执行。本文将介绍几种常见的方法来实现这一需求&#xff0c;并提供详细的代码示例。 1. 使用 Thread.join() Thread.join() 是最简单直接的方法&#xff0c;它会让当前线程等待目标线程执行完毕…...

AWK 入门教程:强大的文本处理工具

AWK 是一种强大的文本处理工具&#xff0c;广泛用于 Linux/Unix 系统中对文本文件或数据流进行操作。它能够基于条件筛选、统计字段、重新排列数据等。主要特点包括&#xff1a; 2. AWK 的基本语法 2.1 AWK 程序的结构 AWK 程序的结构: awk pattern { action } file 2.2 常…...

【Linux】在VMWare中安装Ubuntu操作系统(2025最新_Ubuntu 24.04.2)#VMware安装Ubuntu实战分享#

今天田辛老师为大家带来一篇关于在VMWare虚拟机上安装Ubuntu系统的详细教程。无论是学习、开发还是测试&#xff0c;虚拟机都是一个非常实用的工具&#xff0c;它允许我们在同一台物理机上运行多个操作系统。Ubuntu作为一款开源、免费且用户友好的Linux发行版&#xff0c;深受广…...

基于yolov8+streamlit实现目标检测系统带漂亮登录界面

【项目介绍】 基于YOLOv8和Streamlit实现的目标检测系统&#xff0c;结合了YOLOv8先进的目标检测能力与Streamlit快速构建交互式Web应用的优势&#xff0c;为用户提供了一个功能强大且操作简便的目标检测平台。该系统不仅具备高精度的目标检测功能&#xff0c;还拥有一个漂亮且…...

安装 Powerlevel10k 及 Oh My Zsh 的使用

1. 简介 Powerlevel10k 是 Oh My Zsh 最流行的终端主题&#xff0c;它不仅美观&#xff0c;还提供 Git 状态显示、命令执行时间、网络状态、Python 虚拟环境指示等 实用功能。相比其他主题&#xff0c;Powerlevel10k 速度更快、可定制性更强。 本教程将详细介绍如何安装 Powe…...

虚拟机下ubuntu进不了图形界面

6.844618] piix4_smbus 0000:07.3: SMBus Host ContrFoller not enabled! 7.859836] sd 2:0:0:0:0: [sda] Assuming drive cache: wirite through /dev/sda1: clean, 200424/1966080 files, 4053235/7864064 blocks ubuntu启动时&#xff0c;卡在上面输出位置 当前遇到的原因…...

从 root 一滴水看 Spring Data JPA 的汪洋大海

&#x1f525; 从 root 一滴水看 Spring Data JPA 的汪洋大海 &#x1f30a; 在 Spring Data JPA 的世界里&#xff0c;Specification 是个让人又爱又恨的家伙 &#x1f4a1;。它能帮你动态构建查询&#xff0c;但那个神秘的 Root<T> root 却总让人摸不着头脑&#xff1…...

二进制安装指定版本的MariaDBv10.11.6

一、官网下载mariadb安装包 Download MariaDB Server - MariaDB.org 找到对应的版本 下载安装包后上传到服务器这里不再赘述。 二、安装二进制包 1、解压安装包 2、查看安装包内的安装提示文档根据提示文档进行安装 # 解压安装包 tar xf mariadb-10.11.6-linux-systemd-x8…...

日志Python安全之SSTI——Flask/Jinja2

ssti的概念和模板引擎介绍等基础知识前面已经学过了&#xff0c;接下来直接进入正题 先了解flask/jinja2&#xff1a; flask&#xff1a; 用python编写的一个框架&#xff0c;集成 Jinja2 模板引擎&#xff08;用于动态生成 HTML 内容&#xff09;。 Flask 的核心组件&…...

梯度下降法以及随机梯度下降法

梯度下降法就是在更新weight的时候&#xff0c;向函数值下降的最快方向进行更新&#xff0c;具体的原理我就不再写了&#xff0c;就是一个求偏导的过程&#xff0c;有高数基础的都能够很快的理解过程。我在我的github里面会一直更新自己学习pytorch的过程&#xff0c;地址为&am…...

从零基础到能独立设计单片机产品,一般需要经历哪些学习阶段?

相信很多人&#xff0c;内心都有“钢铁侠”的幻想&#xff0c;成为能写程序&#xff0c;能设计硬件&#xff0c;能设计结构&#xff0c;能焊接的全能型人才。 上次徐工问我&#xff0c;如果你财富自由了&#xff0c;想去做啥&#xff1f; 我说出来&#xff0c;可能大家都不信&a…...