从零实现Web服务器(二): 线程池以及线程池的作用,Get和Post的区别,项目中如何编写数据库连接池,定时器优化非活跃连接
文章目录
- 一、线程池以及线程池的作用
- 二、手写线程池
- 三、Get和Post的区别
- 四、如何编写数据库连接池
- 五、定时器优化非活跃连接
- 5.1. 基于排序链表实现。
- 5.2. 基于小根堆实现。
- 5.3. 基于红黑树实现。
- 5.4. 基于时间轮实现。
- 5.4.1 单时间轮实现
- 5.4.2 多时间轮实现
一、线程池以及线程池的作用
所谓线程池,其实就是一个pthread_t类型的普通数组,通过pthread_create()函数创建m_thread_number个线程,用来执行thread_worker()函数以执行每一个请求处理函数(比如http请求的process函数),通过pthread_detach()将线程设置为脱离态(detached)之后,当这一线程运行结束的时候,它的资源会被系统自动回收,而不再需要手动地,在别的线程中对该需要回收的线程进行pthread_join()操作。
注意:在操作线程池的工作队列的时候,一定要加锁,因为它被所有线程共享。并且我们用信号量来标识请求队列中的请求数,通过m_request.wait();来等待一个请求队列出现待处理的HTTP请求,然后交给线程池中的空闲线程来处理。
二、手写线程池
手写一个线程池??
#include<vector>
#include<string>
#include<list>
#include<thread>
#include<condition_variable>
using namespace std;
class ThreadPool{
public:ThreadPool(int threadnum):started(false),thread_num(thread_num){}~ThreadPool(){stop();for(int i=0;i<thread_num;i++) threadlist[i]->join();for(int i=0;i<thread_num;i++) delete threadlist[i];threadlist.clear();}void thread_worker(){} //线程执行函数,可以自定义捏int getThreadnum(){return thread_num;}void start(){if(thread_num > 0){started=true;for(int i =0;i<thread_num;i++){thread* pthread = new thread(&thread_worker,this);threadlist.push_back(pthread);}}}void stop(){started=false;**condition.notify_all();**}
private:int thread_num;bool started;vector<thread*> threadlist;condition_variable condition;
};
三、Get和Post的区别
偷一个图
四、如何编写数据库连接池
先说说项目中为什么我们需要编写数据库连接池,由于这是一个高并发的服务器,如果说每次用户请求我们都需要新建一个数据库连接,请求结束后我们释放该数据库连接,当用户请求连接过多时,这种做法过于低效,所以类似线程池的做法,我们构建一个数据库连接池,预先生成一些数据库连接放在那里供用户请求使用。
我们先看看单个数据库连接是如何生成的:
1.使用mysql_init()初始化连接
2.使用mysql_real_connect()建立一个到mysql数据库的连接
3.使用mysql_query()执行查询语句
4.使用result = mysql_store_result(mysql)获取结果集
5.使用mysql_num_fields(result)获取查询的列数,mysql_num_rows(result)获取结果集的行数
6.通过mysql_fetch_row(result)不断获取下一行,然后循环输出
7.使用mysql_free_result(result)释放结果集所占内存
8.使用mysql_close(conn)关闭连接
对于一个数据库连接池来讲,就是预先生成多个这样的数据库连接,然后放在一个链表中,同时维护最大连接数MAX_CONN,当前可用连接数FREE_CONN和当前已用连接数CUR_CONN这三个变量。同样注意在对连接池操作时(获取,释放),要用到锁机制,因为它被所有线程共享
五、定时器优化非活跃连接
如果某一个用户connect()到服务器之后,长时间不交换数据,就会一直占用服务器端的文件描述符,导致连接资源的浪费。这个时候就应该利用定时器将这些超时的非活跃连接释放掉。
有这么几种实现方式:
5.1. 基于排序链表实现。
我们监听SIGALRM信号,利用alarm函数周期性的触发SIGALRM信号,信号处理函数利用管道通知主循环,主循环接收到该信号后对升序链表上所有定时器进行处理,若该段时间内没有交换数据,则将该连接关闭,释放所占用的资源。
5.2. 基于小根堆实现。
5.3. 基于红黑树实现。
Nginx中采用了这个方案。
5.4. 基于时间轮实现。
最优的实现方案。
5.4.1 单时间轮实现
单时间轮只有一个由bucket串起来的轮子,下图所示的时间轮有8个bucket,每个bucket下链接着未来对应时刻到期的节点。假设图中相邻bucket到期时间的间隔为slot=1s,从当前时刻0s开始计时,1s时到期的定时器节点挂在bucket[1]下,2s时到期的定时器节点挂在bucket[2]下……当tick检查到时间过去了1s时,bucket[1]下所有节点执行超时动作,当时间到了2s时,bucket[2]下所有节点执行超时动作…….
5.4.2 多时间轮实现
Linux所实现的多时间轮算法,借鉴了日常生活中水表的度量方法,通过低刻度走得快的轮子带动高一级刻度轮子走动的方法,达到了仅使用较少刻度即可表示很大范围度量值的效果。
相关文章:
从零实现Web服务器(二): 线程池以及线程池的作用,Get和Post的区别,项目中如何编写数据库连接池,定时器优化非活跃连接
文章目录一、线程池以及线程池的作用二、手写线程池三、Get和Post的区别四、如何编写数据库连接池五、定时器优化非活跃连接5.1. 基于排序链表实现。5.2. 基于小根堆实现。5.3. 基于红黑树实现。5.4. 基于时间轮实现。5.4.1 单时间轮实现5.4.2 多时间轮实现一、线程池以及线程池…...
为什么伟大的产品只专注做一件事
uber 不允许你预订出租车。亚马逊一开始只是卖书。谷歌只是一个搜索引擎。麦当劳没有餐具。不知为什么,我们仍然相信一个产品要想成功,它必须做很多事情。这通常发生在两种情况下:当新产品试图让市场相信它们是值得的,或者当公司提…...
pycharm远程连接服务器,并单步调试服务器上的代码
每天都有不同的朋友来Push我 那如果比较健忘的话,为啥不问一下chatGPT呢 问题的缘由在我想在本地单步调试代码。。。 我的代码完全在云端服务器的,还有数据集都是,但实际上本地代码可以通过pycharm给他传上去。 但是在后面配置的时候需要两…...
JVM05 方法区
Person:存放在元空间,也可以说方法区 person:存放在Java栈的局部变量表中 new Person():存放在Java堆中 1.方法区的理解 方法区主要存放的是 Class,而堆中主要存放的是 实例化的对象 方法区(Method Area…...
盘点3个.Net开发的WMS仓库管理系统
更多开源项目请查看:一个专注推荐.Net开源项目的榜单 仓库管理系统在企业中,重要性越来越高,不仅可以提高效率,还能降低企业的压力,企业通过协调和优化资源使用和物料流动,能极大程度地提升了管理效率&…...
Linux下Java项目开机自动启动
Linux下Java项目开机自动启动1、在Linux上设置开机启动Java程序,例如:test.jar在Linux上启动Java程序的命令:2、可以将程序启动的指令做成一个shell脚本,简单的做法创建一个test.sh文件,内容如下:3、最重要的一步就是修…...
基于SpringBoot的智慧社区网站
文末获取源码 开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7/8.0 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包:Maven3.3.9 浏…...
数据分析与SAS学习笔记3
SAS在最新的展示图,表现力比较丰富。 SAS的处理流程: 数据步 过程步: ETL是数据分析非常重要的步骤。70%-90%花在收集数据以及整理数据,数据分析数据的时间不是很多的。 一个完整的数据步和过程步: 数据步基本语句总…...
天干地支蓝桥杯国赛
题目 分析 蓝桥杯国赛2020简单模拟题,你敢信,就是弄两个字符串数组。重点在于知道0000年是从哪个天干和地支开始的。 代码 #include <iostream> using namespace std;int year;int main() {cin >> year;string tiangan[10] {"geng&…...
Source lnsight工具的简单使用
多文件编程推荐用Source lnsight工具来进行编写 一、Source lnsight工具的简单使用 1、在桌面上新建一个文件夹factory,在文件夹里新建一个cat.c文件和si文件夹 2、打开Source lnsight工具,点击上方Project--->New Project 3、把文件夹factory中si文…...
100个变态的软件测试面试题及答案!——看完变态面试官对你竖起大拇指!
【纯干货!!!】花费了整整3天,整理出来的全网最实用软件测试面试大全,一共30道题目答案的纯干货,希望大家多多支持,建议 点赞!!收藏!!长文警告&…...
Windows保护机制GS:原理及SEH异常处理突破
前言 本次文章只用于技术讨论,学习,切勿用于非法用途,用于非法用途与本人无关! 所有环境均为本地环境分析,且在本机进行学习。 GS机制并没有对SEH提供保护,换句话说我们可以通过攻击程序的异常处理达到绕…...
大彩 串口屏
资料下载 视频 屏幕程序创建 创建 主界面设置 实现按钮和文本的添加,实现画面的切换 下面注释4有点问题,切换画面还是会下传指令集,只是无法在软件中进行指令集的设置了 按钮界面 首先第一步同上添加背景图片,然后添加…...
安装 cplex 求解器
安装 cplex 求解器 安装 cplex 求解器和python-docplexcplex 安装matlab 用户安装 cplexpython 版本安装 cplex 求解器和python-docplex cplex 安装 cplex 是解决优化问题的一个工具箱,用来线性规划、混合整数规划和二次规划的高性能数学规划求解器。可以理解成&a…...
DPR-34 AC22V【双位置继电器】
系列型号: DPR-20双位置继电器;DPR-31双位置继电器; DPR-32双位置继电器;DPR-33双位置继电器; DPR-34双位置继电器;DPR-35双位置继电器; DPR-11双位置继电器;DPR-12双位置继电器&…...
Ubuntu16.04搭建Fabric1.4环境
一、换源 为了提高下载速度,将ubuntu的源改成国内的源(推荐阿里云源和清华源) apt源保存在 /etc/apt/sources.list / 代表根目录 /etc 这个文件夹几乎放置了系统的所有配置文件 1.备份 sudo cp /etc/apt/sources.list sources_backup.l…...
【JavaScript】深度剖析prototype与__proto__到底是什么以及他们的关系
一个对象的 __proto__ 指向的是这个对象的构造函数的 prototype。 prototype 是什么 prototype 是函数的属性,是一个继承自 Object 的对象,默认的 prototype 只有一个属性,其中包含 constructor,指向当前函数自身。 Ctor.proto…...
css选择器
目录1、基本选择器(1)id选择器(2)类选择器(3)标签选择器(4)逗号选择器(5)*选择器(通配符选择器)2、包含选择器(1ÿ…...
MyBatis详解2——增删改查操作
一、SpringBoot单元测试 1.1什么是单元测试 单元测试是指对软件中的最小测试单元进行检查和验证的过程。 执行单元测试就是为了证明某段代码的执行结果是否符合我们的预期。如果测试通过则是符合预期,否则测试失败。 1.2单元测试的好处 1.单元测试不用启动Tomca…...
最大连续子列和
给定一个数组,求它的最大连续子列和。这个问题有四种解法。 1、暴力循环(O(n^3))分析这个问题,既然是子列,那么它最长为n,最短为1。要想求和我们一般需要知道这个子列的左端下标和右端下标,再求这个子列的和。最简单的…...
线性基 学习笔记
什么是线性基? 先来回顾一下向量空间中的基。这个基代表着空间的一个极大线性无关子集,组中向量线性无关,且空间中的任意一个向量都可以唯一地由基中的向量来表示 那么回到线性基,它其实就类似于是一个向量空间的基 我们考虑一…...
算法-回溯算法-组合问题
77. 组合https://leetcode.cn/problems/combinations/ 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1: 输入:n 4, k 2 输出: [[2,4],[3,4],[2,3],[1,2],[1,3],[1,…...
ABAP中的Null值与space 以及 BW中ADSO的Key值
写出来怪丢人,到现在还没搞懂这个。 在BW中创建ADSO,定义Key字段。可以看到ADSO表的定义中,所有的Key和Data属性如下: 所有的key会有关键字key打头,所有字段都有not null. 但是并不是有个字段是blank空的就不能更新进…...
JavaScript库之Lodash常用方法
Lodash 中文文档https://www.lodashjs.com/docs/lodash.omit/以下总结了在项目中常用的方法,其他的慢慢更新语言:cloneDeep这个方法类似_.clone,除了它会递归拷贝 value。(注:也叫深拷贝)参数value (*): 要…...
Kotlin新手教程二(Kotlin基本数据类型及基础语法)
一、基本数据类型 1.数字 由于Kotlin支持类型推断,所以在使用时若超出Int的范围则会被认定为其它类型;若需要显式指定Long型值,则需要在值后添加L后缀。 2.浮点数 3.比较两个数( 和 ) Kotlin 中没有基础数据类型&a…...
git idea创建新分支,获取/合并主支代码的2个方法
其他sql格式也在更新中,可直接查看这个系列,要是没有你需要的格式,可在评论或私信我 个人目录 获取主支代码的2个方法1,创建一个分支,获取主支的所有代码(场景:我需要一个自己的分支进行编写模…...
CF1714A Everyone Loves to Sleep 题解
CF1714A Everyone Loves to Sleep 题解题目链接字面描述题面翻译题目描述输入格式输出格式样例解释题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1代码实现题目 链接 https://www.luogu.com.cn/problem/CF1714A 字面描述 题面翻译 题目描述 Vlad和其他人一样&am…...
oracle官方下载历史版本JDK版本
背景 日常工作中由于一些特殊原因,我们需要下载指定系统指定位数指定版本的jdk,这个时候去网上搜索下载就会遇到各种坑,病毒、诱导连接、诱导关注/注册、付费、错误版本等,所以最好的办法是去官网下载,下面列举两种方式…...
双击-jar包无法运行解决方法
我自己是通过探索出来的方法解决的,网上的方法适合普通问题 网络流传方法 那种-jar和run.bat的就是曲解了问题意思,问题不是如何运行,而是如何双击jar包就可以直接运行。 普通小问题就是修改注册表,将java路径写进去后面加个 %1…...
程序员的自我修养第七章——动态链接 (下)
接上一篇。 7.3 地址无关代码 对于现代机器来说,引入地址无关代码并不麻烦,我们展示下各种模型的地址引用方式: 1. 模块内部函数调用 2. 模块内部的数据访问,如全局变量、静态变量。 3. 模块外部的函数调用,跳转。 4.…...
宿迁公司做网站/百度搜索使用方法
最近做了一个项目,里面用到了视频播放这一块,当时想考虑Vitamio,demo也做了出来,但是后来发现它是商业收费的,并且收费相当可观,所以只能放弃了。然后找到了ijkPlayer,功能也很强大,…...
为什么会有人攻击我用织梦做的网站/网站友链交换平台
<script>document.write("<script typetext/javascript src//site.com/js.js?v" Date.now() "><\/script>");</script> 使用了网友的上述方法之后,导致了 layui的 折叠面板 异常无法点击 layui-collapse 排查了3…...
如何利用淘宝建设网站挣钱/推广引流app
这几个月以来,一直有人发信或者发消息问GAE的中文问题,也怪我,一直没有好好整理出什么文档。在这里简单地写一个吧以StringProperty和TextProperty这两种类型来举个小例子:====&…...
阿里云虚拟主机怎么建立网站/免费个人网站模板
知己知彼才能百战不殆。要想回答好问题就要先思考面试官的提问的动机。 首先我们分析一下面试官为什么要问这个问题,通过这个问题的答案他希望能获取到什么信息,然后我们把他希望获取到信息表达出来就可以了。面试官通过这个问题主要想了解三个方面&…...
备案上个人网站和企业网站的区别/学seo哪个培训好
OA实施方法论团队建设项目经理的人选要求是具备一定软件技术的、更强调非技术方面的顾问咨询、项目管理的综合素质很强的人才。有效控制项目质量、项目进度、带领团队成功完成项目实施,是九思软件项目经理的职责,而不是合同签订下来,派个会…...
家居网站开发项目计划书/网络推广怎么做效果好
IBM SPSS Statistics为用户提供了三种相关性分析的方法,分别是双变量分析、偏相关分析和距离分析,三种相关分析方法各针对不同的数据情况,接下来我们将为大家介绍如何使用SPSS相关性分析中的距离分析。 一、数据简述 距离分析和其他两类相关…...