Linux:同步
目录
一、同步概念
条件变量
二、生产者消费者模型
三、环形队列
一、同步概念
互斥用来解决 访问临界资源 的非原子性,通俗来说,由于互斥锁的实现,保证了在用户角度看,同一个时间内访问临界资源的代码只有一个线程在执行。
而同步,用来解决,多线程中,临界资源长时间被同一个线程占用,造成其他线程饥饿的问题。
条件变量
条件变量用来实现同步。接口的使用和互斥类似。
条件变量的作用就是,当一个线程拿到锁,访问临界资源结束后,让这个线程去某个条件变量的队列中去等待,同时释放锁资源。
不使用同步机制造成的现象。
使用同步机制改善。
#include <iostream>
#include <vector>
#include <pthread.h>
#include <unistd.h>pthread_mutex_t gmutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t gcond = PTHREAD_COND_INITIALIZER;void* MCore(void* args)
{sleep(3);std::cout << "master 开始工作" << std::endl;std::string name = static_cast<char*>(args);while(1){pthread_cond_signal(&gcond);//唤醒其中一个队列首部的线程std::cout << "master唤醒一个线程" << std::endl;sleep(1);}}
void StartMaster(std::vector<pthread_t>* threads)
{pthread_t tid;int n = pthread_create(&tid,nullptr,MCore,(void*)"Master Thread");if(n == 0){std::cout << "create master success" << std::endl;}threads->emplace_back(tid);
}void* SCore(void* args)
{std::string name = static_cast<char*>(args);while(1){//1.加锁pthread_mutex_lock(&gmutex);//2.条件变量pthread_cond_wait(&gcond,&gmutex);std::cout << "当前被唤醒的线程是:" << name << std::endl;sleep(1);//3.解锁pthread_mutex_unlock(&gmutex);}}
void StartSlaver(std::vector<pthread_t>* threads,int n)
{for(int i = 0;i < n;++i){char* name = new char[64];snprintf(name,64,"new thread-%d",i+1);pthread_t tid;int n = pthread_create(&tid,nullptr,SCore,(void*)name);if(n == 0){std::cout << "create success:" << name << std::endl;threads->emplace_back(tid);}}
}void WaitThread(std::vector<pthread_t>& threads)
{for(auto& tid: threads){pthread_join(tid,nullptr);}
}
int main()
{std::vector<pthread_t> threads;StartMaster(&threads);StartSlaver(&threads,5);WaitThread(threads);return 0;
}
当副线程获取锁资源后,对锁的管理变成不会立刻释放锁,而是去指定的条件变量(队列)下去等待,等待被唤醒,同时释放锁,锁资源同时给到那个被唤醒的进程。
二、生产者消费者模型
- 解释生产者消费者模型
生产者消费者模型,用来解决,并发运行下,多个线程之间的数据传递问题。
- 3个关系
并发运行下:
多个生产者线程之间,既要同步也要互斥
多个消费者线程之间,既要同步也要互斥
生产者和消费者之间,既要同步也要互斥
- 2种角色
生产者、消费者
- 一种交易场所
交易场所本质就是内存中的一种数据结构,交易对象是数据。
- 基于阻塞队列实现生产者消费者模型
交易场所是阻塞队列。
多个生产线程之间要互斥,只能有一个生产线程向阻塞队列放数据。
多个消费线程之间要互斥,只能有一个消费线程向阻塞队列拿数据。
每一个生产线程和每一个消费线程之间要互斥。因此,所有线程都要互斥的访问这个阻塞队列,只需要一把互斥锁即可,但是需要两个条件变量。
基于阻塞队列实现生产者消费者的项目地址
BlockQueue.hpp
#ifndef __BLOCK_QUEUE_HPP__
#define __BLOCK_QUEUE_HPP__#include <iostream>
#include <string>
#include <queue>
#include <pthread.h>template <typename T>
class BlockQueue
{private:bool IsFull(){return _blockqueue.size() == _cap;}bool IsEmpty(){return _blockqueue.empty();}
public:
BlockQueue(int cap)
:_cap(cap)
{_product_wait_num = 0;_consum_wait_num = 0;pthread_mutex_init(&_mutex,nullptr);pthread_cond_init(&_consum_cond,nullptr);pthread_cond_init(&_product_cond,nullptr);
}~BlockQueue()
{pthread_mutex_destroy(&_mutex);pthread_cond_destroy(&_consum_cond);pthread_cond_destroy(&_product_cond);
}
//生产者是向阻塞队列里面加数据
void Enqueue(T & in)
{pthread_mutex_lock(&_mutex);//生产者拿到了队列,判断队列是否为满的//如果是满的,则需要通知消费者来消费,让后让该生产者去等待while(IsFull())//为什么是while而不是if,保证唤醒的进程争夺锁成功后,要确保队列中有数据再去执行后面的代码{_product_wait_num++;//++和--操作pthread_cond_wait(&_product_cond,&_mutex);_product_wait_num--;}//生产_blockqueue.push(in);if(_consum_wait_num > 0){pthread_cond_signal(&_consum_cond);}pthread_mutex_unlock(&_mutex);}
//消费者是从队列里面拿数据
void Pop(T * out)
{pthread_mutex_lock(&_mutex);while(IsEmpty()){//如果队列为空,消费者就去等待,同时释放锁_consum_wait_num++;pthread_cond_wait(&_consum_cond,&_mutex);_consum_wait_num--;}//消费*out = _blockqueue.front();_blockqueue.pop();if(_product_wait_num > 0){pthread_cond_signal(&_product_cond);}pthread_mutex_unlock(&_mutex);
}
private:std::queue<T> _blockqueue;
int _cap;
pthread_mutex_t _mutex;//保护阻塞队列的锁
pthread_cond_t _consum_cond;
pthread_cond_t _product_cond;int _product_wait_num;
int _consum_wait_num;};#endif
Thread.hpp
#ifndef __THREAD_HPP__
#define __THREAD_HPP__#include <iostream>
#include <string>
#include <functional>#include <unistd.h>
#include <pthread.h>namespace ThreadModule
{template<typename T>using func_t = std::function<void(T)>;template<typename T>class Thread{public:Thread(func_t<T> func,T data,const std::string &name = "none-name"):_func(func),_data(data),_threadname(name),_stop(true){}~Thread(){}//这里涉及到了一套解决方案,静态成员函数是类级别的,换句话说,每个对象拿到的函数是同一个,//因此,通过输入型参数代入this指针,再调函数来实现多个对象各自调用void Excute(){_func(_data);}static void* threadroutine(void* args){Thread<T> *self = static_cast<Thread<T>*>(args);self->Excute();return nullptr;}bool Start(){int n = pthread_create(&_tid,nullptr,threadroutine,this);if(!n){_stop = false;return true;}else{return false;}}void Detach(){if(!_stop){pthread_detach(_tid);}}void Join(){if(!_stop){pthread_join(_tid,nullptr);}}std::string name(){return _threadname;}void Stop(){_stop = true;}private:pthread_t _tid;std::string _threadname;T _data;//此时是阻塞队列,是一个共享资源func_t<T> _func;bool _stop;};}#endif
Task.hpp
#pragma once#include <iostream>
#include <string>
#include <functional>//using Task = std::function<void()>;class Task
{
public:Task() {}Task(int a, int b) : _a(a), _b(b), _result(0){}void Excute(){_result = _a + _b;}std::string ResultToString(){return std::to_string(_a) + "+" + std::to_string(_b) + "=" + std::to_string(_result);}std::string DebugToString(){return std::to_string(_a) + "+" + std::to_string(_b) + "=?";}private:int _a;int _b;int _result;
};
Main.cc
#include "Thread.hpp"
#include "BlockQueue.hpp"
#include <vector>
#include <cstdlib>
#include <ctime>
#include "Task.hpp"
using namespace ThreadModule;using blockqueue_t = BlockQueue<Task>;class ThreadData
{public:ThreadData(blockqueue_t & bq,std::string name):_bq(bq),who(name){}blockqueue_t &_bq;std::string who;
};void Consumer(ThreadData* td)
{while(1){sleep(1);//1.从阻塞队列中取一个任务Task t;td->_bq.Pop(&t);//2.处理这个任务t.Excute();std::cout << "Consumer Task" << t.ResultToString() << std::endl;}
}
void Product(ThreadData* td)
{srand(time(nullptr)^ pthread_self());while(1){sleep(1);//1.生成任务int a = rand() % 10 +1;usleep(1000);int b = rand() % 20 + 1;Task t(a,b);//2.把任务放到阻塞队列中td->_bq.Enqueue(t);std::cout << "Product Task" << t.DebugToString() << std::endl;}
}void StartConsumer(std::vector<Thread<ThreadData*>> * threads,int num,blockqueue_t& bq)
{for(int i = 0;i < num; ++i){std::string name = "thread-" + std::to_string(i+1);ThreadData* td = new ThreadData(bq,name);threads->emplace_back(Consumer,td,name);threads->back().Start();//每新建一个线程就启动它}
}
void StartProductor(std::vector<Thread<ThreadData*>> * threads,int num,blockqueue_t& bq)
{for(int i = 0;i < num; ++i){std::string name = "thread-" + std::to_string(i+1);ThreadData* td = new ThreadData(bq,name);threads->emplace_back(Product,td,name);threads->back().Start();//每新建一个线程就启动它}
}
void WaitAllThread(std::vector<Thread<ThreadData*>>& threads)
{for(auto& e : threads){e.Join();}
}int main()
{blockqueue_t* bq = new blockqueue_t(5);//队列最多有五个数据std::vector<Thread<ThreadData*>> threads;StartConsumer(&threads,1,*bq);StartProductor(&threads,1,*bq);WaitAllThread(threads);}
三、环形队列
- 基于环形队列的生产者消费者模型,不再是条件变量控制,而是信号量机制
信号量机制中,将临界资源视为一个整体,就是基于阻塞队列实现的生产者消费者模型。而将临界资源划分为一块块小的数据块,信号量就是用来表示临界资源的数量,信号量的使用,主要表现为基于环形队列实现的生产者消费者模型。
和System的信号量通信方式有一定关联,此处的信号量机制是POSIX中的信号量机制,更多是用来完成生产消费模型。
RingQueue.hpp
#ifndef __RING_QUEUE_HPP__
#define __RING_QUEUE_HPP__#include <iostream>
#include <string>
#include <vector>
#include <pthread.h>
#include <semaphore.h>template<typename T>
class RingQueue
{private:void P(sem_t& sg){sem_wait(&sg);//p操作对应的函数,执行该函数,信号量资源如果大于0,则减减}void V(sem_t& sg){sem_post(&sg);}void Lock(pthread_mutex_t& mutex){pthread_mutex_lock(&mutex);}void Unlock(pthread_mutex_t& mutex){pthread_mutex_unlock(&mutex);}public:RingQueue(int cap):_cap(cap){_productor_step = 0;_consumer_step = 0;pthread_mutex_init(&_productor_mutex,nullptr);pthread_mutex_init(&_consumer_mutex,nullptr);sem_init(&_room_sem,0,_cap);sem_init(&_data_sem,0,0);}~RingQueue(){sem_destroy(&_room_sem);sem_destroy(&_data_sem);pthread_mutex_destroy(&_productor_mutex);pthread_mutex_destroy(&_consumer_mutex);}void Enqueue(const T& in){//生产任务//P操作申请一个空间P(_room_sem);//多个生产者进程之间要互斥Lock(_productor_mutex);_ring_queue[_productor_step++] = in;//生产者按照顺序生产_productor_step %= _cap;Unlock(_productor_mutex);V(_data_sem);}void Pop(T* out){P(_data_sem);Lock(_consumer_mutex);*out = _ring_queue[_consumer_step++];_consumer_step %= _cap;Unlock(_consumer_mutex);V(_room_sem);}private://1.定义一个环形队列std::vector<T> _ring_queue;int _cap;//环形队列的容量上限//2.生产者和消费者的下标int _productor_step;int _consumer_step;//3.定义信号量sem_t _room_sem;//生产者关心有几个空间sem_t _data_sem;//消费者关心有几个数据//4.定义锁,维护多生产多消费之间的互斥的关系,//注意生产者和消费者之间不需要互斥,因此需要两把锁pthread_mutex_t _productor_mutex;pthread_mutex_t _consumer_mutex;};#endif
相关文章:
Linux:同步
目录 一、同步概念 条件变量 二、生产者消费者模型 三、环形队列 一、同步概念 互斥用来解决 访问临界资源 的非原子性,通俗来说,由于互斥锁的实现,保证了在用户角度看,同一个时间内访问临界资源的代码只有一个线程在执行。 而…...
GB28181开发--ZLMediaKit+WVP+Jessibuca
一、核心组件功能 1、ZLMediaKit 定位:基于 C++11 的高性能流媒体服务框架,支持 RTSP/RTMP/HLS/HTTP-FLV 等协议互转,具备低延迟(最低 100ms)、高并发(单机 10W 级连接)特性,适用于商用级流媒体服务器部署。 特性:跨平台(Linux/Windows/ARM 等)、支持 …...
23种设计模式之《备忘录模式(Memento)》在c#中的应用及理解
程序设计中的主要设计模式通常分为三大类,共23种: 1. 创建型模式(Creational Patterns) 单例模式(Singleton):确保一个类只有一个实例,并提供全局访问点。 工厂方法模式࿰…...
Oracle删除重复数据保留其中一条
Oracle删除重复数据保留其中一条 在Oracle数据库中,要删除重复数据并保留其中一条记录,可以使用多种方法。这里介绍两种常见的方法:使用ROWID或使用ROW_NUMBER()窗口函数。 方法1:使用ROWID ROWID是Oracle中用来唯一标识表中每…...
deepseek助力运维和监控自动化
将DeepSeek与Agent、工作流及Agent编排技术结合,可实现IT运维与监控的智能化闭环管理。以下是具体应用框架和场景示例: 一、智能Agent体系设计 多模态感知Agent 日志解析Agent:基于DeepSeek的NLP能力,实时解析系统日志中的语义&a…...
16.1STM32_ADC
STM32_ADC 数字信号分为高/低电平两种状态 模拟信号就是任意的电压值 STM32芯片内就是一整套的数字逻辑电路,来实现我们的程序执行,以及各种各样的外设功能, ADC(模拟-数字转换技术)的功能就是将模拟信号转化为数字…...
神经网络 - 激活函数(Swish函数、GELU函数)
一、Swish 函数 Swish 函数是一种较新的激活函数,由 Ramachandran 等人在 2017 年提出,其数学表达式通常为 其中 σ(x) 是 Sigmoid 函数(Logistic 函数)。 如何理解 Swish 函数 自门控特性 Swish 函数可以看作是对输入 x 进行“…...
VS2015 c++和cmake配置编程
Visual Studio 2015:确保安装了C开发工具,并安装“使用C的桌面开发”工作负载。CMake:可以从 CMake官网 下载并安装,并将其添加到系统环境变量中。vs加载项目启动Visual Studio。选择“继续但无代码”。点击“文件”。选择 “打开…...
如何为 Web 前端开发面试做好准备
大家好!我是 [数擎AI],一位热爱探索新技术的前端开发者,在这里分享前端和Web3D、AI技术的干货与实战经验。如果你对技术有热情,欢迎关注我的文章,我们一起成长、进步! 开发领域:前端开发 | AI 应…...
深入探索像ChatGPT这样的大语言模型
参考 【必看珍藏】2月6日,安德烈卡帕西最新AI普及课:深入探索像ChatGPT这样的大语言模型|Andrej Karpathy fineweb知乎翻译介绍 fineweb-v1原始连接 fineweb中文翻译版本 Chinese Fineweb Edu数据集 查看网络的内部结果,可以参…...
代码贴——堆(二叉树)数据结构
头文件Heap.h #pragma once #include<bits/stdc.h> typedef int HPDataType;typedef struct Heap {HPDataType* a;int size;int capacity; }HP;void HPInit(HP* php); void HPDestory(HP* php); //出入后保持数据是堆 void HPPush(HP* php,HPDataType x); HPDataType HP…...
office或者word排版中,复制/黏贴进来文字不会自动换行,如何处理?
李升伟 整理 一、思考与分析 在Office或Word中复制粘贴文字时,文字不会自动换行,需要处理这个问题。首先,我得回想一下常见的原因和解决方法。可能的情况有很多,比如文本带有硬回车、段落格式设置问题,或者文本框的自…...
最新!!!DeepSeek开源周发布内容汇总
本周,人工智能领域的新锐力量DeepSeek宣布将于本周举办“开源周”(Open Source Week),连续五天每日开源一个核心代码库,以透明的方式与全球开发者分享其在通用人工智能(AGI)探索中的最新成果。以…...
【MySQL】(2) 库的操作
SQL 关键字,大小写不敏感。 一、查询数据库 show databases; 注意加分号,才算一句结束。 二、创建数据库 {} 表示必选项,[] 表示可选项,| 表示任选其一。 示例:建议加上 if not exists 选项。 三、字符集编码和排序…...
记一次渗透测试实战:SQL注入漏洞的挖掘与利用
0x01 漏洞发现 在对某网站进行安全测试时,发现以下URL存在异常: https://******.com/search.php?keyword1&zt1954&dw1885&zz& 当参数keyword和zt被赋值为-1时页面返回特殊内容,初步判断存在SQL注入漏洞。 0x02 注入验证…...
Gin框架从入门到实战:核心用法与最佳实践
为什么选择Gin框架? Gin 是一个基于 Go 语言的高性能 Web 框架,具备以下优势: 轻量高效:底层依赖 net/http,性能接近原生。简洁优雅:API 设计友好,支持路由分组、中间件链、参数绑定等特性。生…...
PyTorch 的 nn.NLLLoss:负对数似然损失全解析
PyTorch 的 nn.NLLLoss:负对数似然损失全解析 在 PyTorch 的损失函数家族中,nn.NLLLoss(Negative Log Likelihood Loss,负对数似然损失)是一个不太起眼但非常重要的成员。它经常跟 LogSoftmax 搭配出现,尤…...
ROS2软件调用架构和机制解析:Publisher创建
术语 DDS (Data Distribution Service): 用于实时系统的数据分发服务标准,是ROS 2底层通信的基础RMW (ROS Middleware): ROS中间件接口,提供与具体DDS实现无关的抽象APIQoS (Quality of Service): 服务质量策略,控制通信的可靠性、历史记录、…...
vue2 以及vue3中 v-if和v-for是否可以同时使用
vue2以及vue3官方文档中都明确的指出 避免 v-if 和 v-for 用在一起 vue2 官方文档 解释 在 Vue 2 中,v-for 的优先级高于 v-if,也就是说,Vue 2 在渲染时,会先处理 v-for 生成列表项,再对子项判断 v-if 是否渲染。 …...
Hbase伪分布安装教程,详细版
注意Hbase版本与Hadoop版本的兼容,还有与JDK版本的兼容 本次用到的Hbase为2.4.6版本,Hadoop为3.1.3版本,JDK为JDK8 打开下面的网址查看兼容问题 Apache HBase Reference Guidehttps://hbase.apache.org/book.html#configuration 点击基础先…...
SSL: CERTIFICATE_VERIFY_FAILED Error in Python 是什么问题?
在最新版本的Stable Diffusion webui 版本上使用最新下载的模型时,出现了类似的错误。 SSL: CERTIFICATE_VERIFY_FAILED 错误在Python中通常表示你的程序试图通过HTTPS连接到某个服务器,但Python无法验证该服务器提供的SSL证书。这可能是因为以下几种原…...
15Metasploit框架介绍
metasploit目录结构 MSF ——the metasploit framework 的简称。MSF高度模块化,即框架结构由多个module组成,是全球最受欢迎的工具 是一筐开源安全漏洞利用和测试工具,集成了各种平台上常见的溢出漏洞和流行sheellcode,并且保持…...
【Qt】ffmpeg解码—照片提取、视频播放▲
目录 一、图像的成像原理: RGB成像原理: YUV成像原理: 二、多线程 三、ffmpeg解码(照片提取) 1.准备工作 (1)在工程文件夹里面新建三个文件夹 (2)在main函数中加…...
Springboot整合WebSocket+Redis以及微信小程序如何调用
一、 Springboot整合WebSocket 1. 引入socket依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dependency>引入依赖后需要刷新maven,Websocket的版本默认跟随S…...
HOW - 在Windows浏览器中模拟MacOS的滚动条
目录 一、原生 CSS 代码实现模拟 macOS 滚动条额外优化应用到某个特定容器 二、Antd table中的滚动条场景三、使用第三方工具/扩展 如果你想让 Windows 里的滚动条 模拟 macOS 的效果(细窄、圆角、隐藏默认轨道)。 可以使用以下几种方案: 一…...
openEuler环境下GlusterFS分布式存储集群部署指南
1.环境准备: os:openEuler 22.03 主机名 IP地址 主机用途 Rocky8192.168.121.160客户端 open-Euler1192.168.121.150节点1,提供两块6G硬盘open-Euler4192.168.121.153节点2,提供两块6G硬盘open-Euler5192.168.121.154 …...
C++学习(七)(标准库+STL(iotstream公司,日期/时间,器皿,算法,迭代器,多线程))
C 标准模板库 (STL) C 标准模板库 (STL) 是头文件的集合,提供了多种数据结构、算法和函数,以简化您的 C 编码体验。STL 的主要目的是通过提供一套现成的有用工具来节省时间并提高效率。STL 最常用的功能可…...
c高级第五天
1> 在终端提示输入一个成绩,通过shell判断该成绩的等级 [90,100] : A [80, 90) : B [70, 80) : C [60, 70) : D [0, 60) : 不及格 #!/bin/bash# 提示用户输入成绩 read -p "请输入成绩(0-100):" score# 判断成…...
Windows上使用go-ios实现iOS17自动化
前言 在Windows上运行iOS的自动化,tidevice对于iOS17以上并不支持,原因是iOS 17 引入新通信协议 RemoteXPCQUIC,改变了 XCUITest 的启动方式。 一、go-ios的安装 1、安装命令:npm i go-ios 2、安装完成后输入命令which io…...
迷你世界脚本小地图接口:Mapmark
小地图接口:Mapmark 彼得兔 更新时间: 2023-10-25 10:33:48 具体函数名及描述如下: 序号 函数名 函数描述 1 newShape(...) 新增一个形状(线,矩形,圆形) 2 deleteShape(...) 删除一个形状 3 setShapeColor(...) 设置…...
TMS320F28P550SJ9学习笔记1:CCS导入工程以及测试连接单片机仿真器
学习记录如何用 CCS导入工程以及测试连接单片机仿真器 以下为我的CCS 以及驱动库C2000ware 的版本 CCS版本: Code Composer Studio 12.8.1 C2000ware :C2000Ware_5_04_00_00 目录 CCS导入工程: 创建工程: 添加工程: C…...
为什么要提倡尽早返回(Early Return)
为什么要提倡尽早返回(Early Return) 在编程中,“尽早返回”(Early Return)是一种常被提倡的编程方式,特别是在需要提升代码可读性、减少嵌套层级、以及快速处理异常情况时。本文将讨论尽早返回的优点、应…...
Gartner发布安全运营指标构建指南
如何为安全运营指标构建坚实的基础 安全运营经理需要报告威胁检测、调查和响应计划的有效性,但难以驾驭大量潜在的 SOC 指标。本研究提供了设计针对 SOC 的指标系统的示例和实践。 主要发现 需要清晰、一致的衡量标准来向董事会成员或服务提供商等更广泛的团队传达…...
vue3:初学 vue-router 路由配置
承上一篇:nodejs:express js-mdict 作为后端,vue 3 vite 作为前端,在线查询英汉词典 安装 cnpm install vue-router -S 现在讲一讲 vue3:vue-router 路由配置 cd \js\mydict-web\src mkdir router cd router 我还…...
数据结构入门篇——什么是数据结构。
一、引入 工具是一种什么东西呢?是一种转化媒介,我们需要熟食,我们要通过用火来将生肉烤熟。在这个过程中。我们要输入一个东西——生肉,通过工具——火的加工,从而得到我们的目的产物——熟肉。 将上面的例子和红字部…...
uniapp+vue3搭建项目
工具使用: Pinia Vue 3 官方推荐的状态管理库,比 Vuex 更轻量,支持模块化,结合 persistedstate 插件可以持久化存储数据。uView-plus 专为 UniApp 设计,支持 App、小程序、H5。UnoCSS 更轻量,比 TailwindCS…...
unity大坐标抖动处理测试
第二幅图就是相机坐标是0 6360094 0的地方看见的模型,可以看见这个球体已经烂了 那么这里可以知道的是坐标太大了导致的,那么把所有物体共同偏移一下,即可得到第一幅图的效果,圆润的sphere又回来了 浮点数的计算是需要位数的&…...
CASAIM与承光电子达成深度合作,三维扫描逆向建模技术助力车灯设计与制造向数字化与智能化转型
近日,CASAIM与广州承光电子科技有限公司正式达成深度合作,CASAIM将为承光电子提供全方位的技术支持,包括高精度三维扫描设备、逆向建模软件以及定制化的技术解决方案。双方将共同组建技术团队,针对车灯设计中的难点进行攻关&#…...
C++类与对象:银行管理系统项目实战开发LeetCode每日一题
[Bank-Management-System]银行管理系统项目 以下是一个可运行的C银行账户类(支持简单的存款/取款)。后面会继续完善该项目: #include <iostream> #include <string> using namespace std;class Account{public://构造函数Accou…...
领域驱动设计:事件溯源架构简介
概述 事件溯源架构通常由3种应用设计模式组成,分别是:事件驱动(Event Driven),事件溯源(Event Source)、CQRS(读写分离)。这三种应用设计模式常见于领域驱动设计(DDD)中,但它们本身是一种应用设计的思想,不仅仅局限于DDD,每一种模式都可以单独拿出来使用。 E…...
景联文科技:以专业标注赋能AI未来,驱动智能时代的精准跃迁
在人工智能技术重塑全球产业格局的今天,高质量训练数据已成为驱动算法进化的核心燃料。作为数据智能服务领域的领军者,景联文科技深耕数据标注行业多年,以全栈式数据解决方案为核心,构建起覆盖数据采集、清洗、标注、质检及算法调…...
LeetCode 热题 100----1.两数之和
LeetCode 热题 100----1.两数之和 题目描述 我的解法 语言:js 思路就是:用双重循环去找哪两个数字相加等于target,目前的时间复杂度为O(n2),之后右优化思路再更新。...
GIT 常用命令
/ 一、环境: ssh-keygen -t rsa -C "wangxiaoerqq.com.cn" 生成本地秘钥(邮箱换成自己的邮箱) 使用cat ~/.ssh/id_rsa.pub查看秘钥 git config --global user.name "wangxiaoer" git config --global wangxiaoerqq.…...
Netty笔记13:序列化
Netty笔记1:线程模型 Netty笔记2:零拷贝 Netty笔记3:NIO编程 Netty笔记4:Epoll Netty笔记5:Netty开发实例 Netty笔记6:Netty组件 Netty笔记7:ChannelPromise通知处理 Netty笔记8…...
IntelliJ IDEA 构建项目时内存溢出问题
问题现象 在使用 IntelliJ IDEA 构建 Java 项目时,遇到了以下错误: java: java.lang.OutOfMemoryError: Java heap space java.lang.RuntimeException: java.lang.OutOfMemoryError: Java heap space这是一个典型的 Java 堆内存不足错误,表…...
Asp.Net Core WebAPI开发教程(入门)
一、Asp.Net Core WebAPI项目创建 二、Asp.Net Core WebApi/Mvc路由定义 二、Asp.Net Core WebAPI 请求案例 Asp.Net WebApi Get请求整理(一) Asp.Net WebApi Post请求整理(一) Asp.Net WebApi Action命名中已‘Get’开头问题 …...
golang 内存对齐和填充规则
内存对齐和填充规则 对齐要求:每个数据类型的起始地址必须是其大小的倍数。 int8(1字节):不需要对齐。int16(2字节):起始地址必须是2的倍数。int32(4字节):起…...
MySQL执行更新SQL流程
目录 1 redo log 2 binlog 3 Update执行逻辑 1 redo log InnoDB引擎特有日志MySQL的WAL(Writing Ahead logging)技术,预写式日志,先写日志再写磁盘当有一条记录需要更新时,InnoDB引擎就会先把记录写在redo log日志中&a…...
【时序预测】在线学习:算法选择(从线性模型到深度学习解析)
——如何为动态时序预测匹配最佳增量学习策略? 引言:在线学习的核心价值与挑战 在动态时序预测场景中(如实时交通预测、能源消耗监控),数据以流式(Streaming)形式持续生成,且潜在的…...
CISC架构
基本概念 CISC 架构是一种计算机处理器设计架构,其设计理念与 RISC 架构相对。CISC 架构强调通过使用大量功能复杂的指令来增强计算机的处理能力,试图让计算机用一条指令就能完成较为复杂的操作,以减少程序中指令的总数,提高程序…...