web服务器改进:迷你线程池+CAS自旋锁(Demo)

C++ LinuxWebServer项目(6)压力测试与优化思考 压力测试与服务器优化思考 阅读详情

1. 概述

最近有学习一些关于C++11从语法层面上提供的多线程编程。本来考虑使用C++11的互斥锁来实现线程间的互斥,而C++提供的互斥锁是比较简单的,和Linux的使用没有太大区别。

另一方面,在面试的时候,会涉及一些无锁的互斥手法。比如:在webserver项目中,请求队列的任务在出队和入队上都需要互斥锁。而互斥锁比较重,需要执行系统调用。而系统调用又需要陷入内核态,调度完切换回用户态又需要时间,因此效率较低。这时候,采用CAS+自旋锁的手法效率会比较高。

因此,下面的例子借鉴陈硕大神在muduo网络库实现一个迷你版的线程池。在这个线程池中,我们把线程类Thread和线程池类ThreadPool进行解耦,让模块与模块之间的耦合度更低。在实现细节上:

  1. 其中,ThreadPool类定义了线程池中的子线程的工作函数runInThread,这个在muduo网络库里面其实是开发了个接口给用户进行定义的,但是在这里我们没有提供这个借口,感兴趣的读者可以自行拓展封装。

  2. 我们实现了一个CAS类的自旋锁,其实现使用了C++11提供的原子类atomic。

2. 代码实现

#include <iostream>
#include <thread>
#include <mutex>
#include <functional>
#include <vector>
#include <atomic>
using namespace std;

int mutex = 0;
int lock = 1;
int unlock = 0;

class CAS {
public:
	CAS() : flag(false) {}

	// 上锁
	void lock() {
		bool expect = false;
		// 1. 如果flag的值(锁的值)和期望的值相等,那么将新的值赋给flag,返回true
		// 2. 如果flag的值(锁的值)和期望值不相等,那么将flag的值赋给expect,返回false,因此每次都要重置expect
		while (!flag.compare_exchange_weak(expect, true)) {
			expect = false;
		}
	}

	// 解锁
	void unlock() {
		flag.store(false);
	}

private:
	CAS(const CAS&) = delete;
	CAS& operator=(const CAS&) = delete;
	atomic<bool> flag; // false为解锁状态 true为上锁状态
};


class Thread {
public:
	Thread(function<void()> func) : func_(func) {}

	thread start() {
		thread t(func_);
		return t;
	}

private:
	function<void()> func_;
};

class ThreadPool {
public:

	void startPool(int poolSize) {
		for (int i = 0; i < poolSize; ++i) {
			pool_.push_back(new Thread(bind(&ThreadPool::runInPool, this, i)));
		}

		for (int i = 0; i < poolSize; ++i) {
			handler_.push_back(pool_[i]->start());
		}

		for (int i = 0; i < poolSize; ++i) {
			handler_[i].join();
		}
	}

private:
	// 工作函数
	void runInPool(int threadId) {
		mutex_.lock();
		cout << "Thread start! Thread Id:" << threadId << endl;
		mutex_.unlock();
	}

	vector<Thread*> pool_;
	vector<thread> handler_;

	CAS mutex_;
};


int main() {

	ThreadPool pool;
	pool.startPool(10);

	return 0;
}

图像处理(12)--图像各种噪声及消除方法 文章目录结构1.什么是图像噪声2. 图像噪声来源3. 噪声分类及其消除方法3.1 高斯噪声及其消除方式3.1.1 如何确定一种噪声是高斯噪声3.1.2 高斯滤波消除高斯噪声3.1.3 高斯函数的重要性质3.2 瑞利噪声及其消除方式3.3 伽马(爱尔兰)噪声及其消除方式3.4 指数分布噪声及其消除方式3.5 均匀噪声及其消除方式3.6 脉冲(椒盐)噪声及其消除方式 1.什么是图像噪声 图像噪声是指... 阅读详情

相关推荐

基于Python适用于YOLO目标检测算法的图片数据增强处理

为了增强模型的鲁棒性以及数据的丰富性,同 时为了防止由于数据过少发生过拟合,本设计对数 据集进行数据增强处理,包括随机亮度调节、随机 对比度调节、随机饱和度调节、加入高斯噪声、水 平翻转、运动模糊和旋转 15°

weixin_67136409的博客 699

WebServer项目的亮点和难点

文章目录一、亮点1.采用了Reactor设计模式为什么选择Reactor?WebServer选择的Reactor方案WebServer对Reactor的具体实现2.EPOLLONESHOT3.基于小根堆实现了定时器4.实现了可以自动增长的缓冲区5.线程池二、难点三、有待改进的地方 面试被问到了这个问题,答得稀烂…但是我觉得这个问题真的问的很好,还是要好好想一想总结一下。 亮点: 并发模型为Reactor 使用Epoll水平触发+EPOLLONESHOT,非阻塞IO 为充分利用多核CPU的性能,以多线程的形式

记录学习的点滴 8581

ThreeJS教程:地图案例(包围盒、正投影)

推荐:将加入你的3D工具链。

jianshi2023的博客 1007

TinyWebserver的复现与改进(3):线程同步机制类封装及线程池实现

线程池有许多种实现方法,最容易想到的一种是每有一个新任务、就开一个新线程执行。这种方式最大的缺点是线程数不固定,试想如果在某一时刻有1000个并发请求,那么就需要开1000个线程,如果CPU只有8核或16核,物理上不能支持这么高的并发,那么线程切换会耗费大量的资源。为了避免服务器负载不稳定,这里采用了固定线程数的方法,即启动固定数量的工作线程,一般是CPU核数(物理支持的最大并发数),然后将任务添加到请求队列,工作线程不断主动取出请求队列的任务执行。

yzfzzz的博客 1023

①Modbus TCP转Modbus RTU/ASCII网关同步采集无需编程高速轻松组网

MS-A1-50X1系列作为MODBUS TCP通信的服务器进行动作。可通过MODBUS TCP 通信,将 MS-A1-50X1 系列产品通过 RS485 采集的仪器仪表之类的值作为通信数 据输出到 PLC,上位机等。

2401_89571741的博客 1398

YOLOv11改进策略【Backbone/主干网络】|替换HGNetV2骨干,包含RT-DETR中的l、x模型

本文记录的是基于HGNetv2的YOLOv11目标检测改进方法研究。本文利用HGNetv2替换YOLOv11的骨干网络,HGNetv2 通过其 GPU 推理友好的 3×3 标准卷积和层次化 HG Block 结构,能够为骨干网络提供高效且完整的特征提取能力。并且其中的和可在降低计算量的同时丰富特征表达,增强对多尺度目标特征的捕获能力,进而提高模型精度。本文配置了原论文中rtdetr-lrtdetr-x,以满足不同算力和检测精度的需求。

Limiiiing的博客 670

TinyWebserver的复现与改进(2):项目的整体框架

本文介绍了项目的总体框架,理清了工作顺序,下一步将会按照这个顺序梳理代码。

yzfzzz的博客 1390

【ComfyUI 基础教程】ComfyUI 局部重绘工作流教程

本篇指南将带你了解 ComfyUI 中的局部重绘工作流,并带你完成一个局部重绘的示例,以及遮罩编辑器的使用等。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 303

TinyWebserver的复现与改进(6):定时器处理非活动连接

如果客户端长时间没有动作,会占用了许多连接资源,严重影响服务器的性能。因此需要通过实现一个服务器定时器,处理这种非活跃连接,释放连接资源。

yzfzzz的博客 951

通信原理 | CRC循环冗余校验码(最简介明了的原理和matlab程序)

异或运算: 多项式: CRC校验中用到的除数,是由多项式的各项系数组成的,如下所示: 没有的项系数为0,比如:x5次方、x3次方下一步,在原数据串的末端加“0”0的数量由多项式决定具体来说,多项式的阶数是多少就加几个0 具体操作: 现在,我们有了除数,也有了处理过的数据串,如下所示: 就可以开始计算校验和 了将数据串第一个1与除数左对齐,按位进行异或操作: 将未处理的数据搬下来作为新的数据,重复操作: 将新的数据串第一个1与除数左对齐,再重复按位异或操作: 如此循环,直到所有数据都处理过

若北辰 2357

ArcGIS Pro 3.4 二次开发 - 布局

本文介绍了在ArcGIS Pro SDK 3.4和.NET 8环境下操作布局工程项的相关方法。主要内容包括:引用布局工程项和关联布局,在新视图中打开或激活已有布局视图,引用活动布局视图,导入/移除布局工程项,创建基本布局或带参考线的自定义布局,修改布局页面尺寸,以及创建圆形图形元素等操作。重点演示了如何通过CIM(Core Infrastructure Model)进行高级布局配置,并详细说明了圆形图形元素的创建过程,包括几何构建、符号设置和图形生成。所有涉及UI线程的操作都遵循ArcGIS Pro SDK

Winemonk 795

从零开始自制实现WebServer(八)---- 花费两天解决性能瓶颈问题 介绍一路调试历程以及推荐各种好用的工具

文章目录前引(七)---- 继续整改代码 优化代码逻辑(下) 前引 刚刚在写博客前 想到了好多好多以前自己的往事 回想到 其实这一路走过来 真的觉得自己与绝大部分人走过的 小学初中高中都不同 也包括自己的大学 回想起来自己原来真的自己也做过好多错事 犯过太多太多错误 也做过很多对不起别人的事情 但是距离真的自己感觉到做了错事的时候 在我记忆中 应该是停留在高二的时间了 距离现在也快三年多四年了 有时想想啊 人啊 很多时候做事情真的得三思 思考现在 思考以往 思考未来 也许是这三四年内自己没有在做过什么错

Love 6's Private Blog 3176

第201期 解锁科研效率新高度:Claude 科学技能插件(claude-scientific-skills)深度体验

科研AI助手Claude Scientific Skills开源工具为Claude大模型扩展科学能力,覆盖数据可视化、数学计算、学术格式处理等科研全流程需求。该插件支持LaTeX公式生成、自动化科研图表绘制、学术文档规范校正等功能,让研究人员通过自然语言指令即可完成专业任务。项目开源可定制,支持特定学科需求扩展,目前已托管于GitHub。使用门槛低,只需配置Claude API密钥即可快速启用,帮助科研人员从繁琐技术细节中解放,聚焦核心研究创新。

全网120W+关注AI拉呱,专注人工智能以及科技前沿! 1358

线程同步与互斥 [ 案例 : 线程池 ]

日志系统的设计需要考虑多个方面,包括日志的格式、输出目标(如控制台、文件等)以及线程安全性。C++17引入了文件系统库,使得文件操作更加方便。此外,策略模式允许我们在运行时动态选择日志的输出策略,从而增加了系统的灵活性。单例模式是一种设计模式,像之前单例模式是一种常用的软件设计模式,它确保一个类只有一个实例,并提供一个全局访问点。单例模式的实现需要满足以下两个条件:保证一个类只有一个实例。提供一个全局访问点。

Small_entreprene的博客 1044

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

面试题汇总

高频率面试题

weixin_43766298的博客 868

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Java面试突击:30天构建核心知识体系与实战话术

在软件工程领域,构建高效、可维护的系统离不开对核心编程语言和框架的深入理解。Java作为企业级应用的主流语言,其知识体系庞大,涵盖基础语法、并发编程、虚拟机原理、数据库交互和主流框架等多个维度。理解这些技术的底层原理,例如JVM的内存模型与垃圾回收机制、MySQL的索引数据结构与事务隔离实现,是提升系统性能和稳定性的关键。这些原理在解决高并发、大数据量等实际工程问题时具有重要价值,广泛应用于电商、金融、社交等互联网核心场景。本文聚焦于Java面试中的高频考点,如HashMap的线程安全实现、volatile

weixin_34405354的博客 437

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

2025 Java面试核心指南:JVM、并发、框架原理与系统设计深度解析

Java作为企业级应用开发的主流语言,其技术生态围绕JVM(Java虚拟机)构建,理解JVM的内存模型、垃圾回收机制是掌握Java程序性能调优的基础。并发编程则是提升系统吞吐量的关键技术,涉及线程安全、锁机制及并发工具包(JUC)的应用。在分布式架构成为主流的今天,对Spring框架IoC/AOP原理、MySQL索引与事务、Redis缓存及消息队列等核心组件的深入理解,是构建高可用、高性能系统的基石。本文聚焦Java面试中的高频考点与实战场景,通过剖析JVM内存调优、HashMap扩容机制、秒杀系统设计等典

weixin_33770878的博客 534

TinyWebserver的复现与改进(4):主线程的具体实现

今天我们将采用主从Reactor多线程模式,这是是大多数高性能服务器采用的模式 主从Reactor多线程模式要求主线程(I/O处理单元)只需负责: 1. 监听文件描述符上是否有事件发生, 2. 有的话就立即将该事件通知工作线程(逻辑单元), 3. 将 socket 可读可写事件放入请求队列,交给工作线程处理。 除此之外,主线程不做任何其他实质性的工作。读写数据,接受新的连接,以及处理客户请求均在工作线程中完成。

yzfzzz的博客 1323

c++11总结23——CAS(无锁队列)

1. 概念 CAS(Compare And Swap)操作是一条CPU的原子指令,所以不会有线程安全问题。 伪代码实现: CAS(addr,old,new) 解释:将addr存放的只与old比较,如果等于old,则将new赋值给addr。 c++代码实现: //输入一个pAddr的地址,在函数内部判断其的值是否与期望值nExpected相等 //如果相等那么就将pAddr的值改为nNew并同时返回true;否则就返回false,什么都不做 bool compare_and_swap(in

www_dong的博客 6767

C++实现无锁队列

CAS等原子操作 在介绍无锁队列之前,我们需要知道一个重要的技术就是CAS操作,**现在几乎所有的CPU指令都支持CAS等原子操作。**有了这个原子操作,我们就可以用其来实现各种无锁的数据结构了。 本文用到的是GCC的CAS GCC4.1+版本中支持CAS的原子操作 bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...) type __sync_val_compare_and_swap (type *ptr,

weixin_42250655的博客 3653

从0开始编写webserver·基础篇

(也就是 this )进行传递,即线程创建时调用的arg参数。什么意思呢?我们要调用pthread_create()函数创建一个线程,此时我们需要提供。

Gefangenes的博客 910

学到就是赚到,面试加分项之WebServer线程池管理!

大家好,这篇文章我们来讨论一个话题,怎么去管理 SpringBoot 内置的三大 WebServer(Tomcat、Jetty、Undertow)的线程池,包括监控告警、动态调参。 不管是应对越来越卷的面试考察,还是自己项目日常性能调优,绝对有用,学到就是赚到,搬好椅子,开始我们的分析之旅。 写在前面 要想去管理第三方组件的线程池,首先肯定要对这些组件有一定的熟悉度,了解整个请求的一个处理过程,找到对应处理请求的线程池,这些线程池不一定是 JUC 包下的 ThreadPoolExecutor 类,也可能是

兰陵笑笑生 532

Java 并发编程 第二期:CAS与乐观锁

在讲解 CAS 和乐观锁之前,我们首先需要了解一些基本概念:Java 线程模型以及为什么需要线程模型 Java 线程模型 我们常说线程是进程的子集,一个进程可以有多个线程。但是对于 Linux 系统而言,并没有线程这个概念。我们可以说,在 Linux 中线程等于轻量级的进程。区别在于: 进程拥有独立的内存地址 ,但是线程没有独立的内存地址,多个线程只能共享一个内存的地址。 如图所示,Java 是运行在操作系统中的,那么其线程也对应着操作系统中的每一个线程。对应的,Java线程模型和内核必然存在着某种关

君若雅的博客 731

C++并发编程 | CAS基本原理

C++并发编程 | CAS基本原理

weixin_44479862的博客 1406

C++后端开发(3.2.1)—— 原子操作CAS与锁实现

C++后端开发(3.2.1)—— 原子操作CAS与锁实现简介 小节提纲 1.互斥锁的使用场景与原理 2.自旋锁的性能分析 3.原子操作的汇编实现

weixin_43687811的博客 2198

锁机制及CAS实现原理

文章目录锁机制悲观锁乐观锁锁机制存在的问题两种锁总结CAS(Compare & Set/Compare & Swap)CAS算法原理描述 锁机制 常用的锁机制有两种:悲观锁、乐观锁 悲观锁 假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。 悲观锁的实现,往往依靠底层提供的锁机制。 悲观锁会导致其它所有需要锁的线程挂起,等待持有锁的线程释放锁。 乐观锁 假设不会发生并发...

qq_43313035 1837
上一篇: 有向图、无向图相关数据结构
下一篇: 设计模式:适配器模式(C++实现)
zsiming
博客等级 码龄7年 43粉丝 74原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值