从零实现Web服务器(二): 线程池以及线程池的作用,Get和Post的区别,项目中如何编写数据库连接池,定时器优化非活跃连接

news2024/11/18 13:26:51

文章目录

  • 一、线程池以及线程池的作用
  • 二、手写线程池
  • 三、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所实现的多时间轮算法,借鉴了日常生活中水表的度量方法,通过低刻度走得快的轮子带动高一级刻度轮子走动的方法,达到了仅使用较少刻度即可表示很大范围度量值的效果。

在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/349801.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaScript 入门教程||javascript 简介||JavaScript 用法

javascript 简介JavaScript 是互联网上最流行的脚本语言&#xff0c;这门语言可用于 HTML 和 web&#xff0c;更可广泛用于服务器、PC、笔记本电脑、平板电脑和智能手机等设备。JavaScript 是脚本语言JavaScript 是一种轻量级的编程语言。JavaScript 是可插入 HTML 页面的编程代…

C++之lambda函数(匿名函数)

lambda函数简介lambda函数是C11标准新增的语法&#xff0c;也称为lambda表达式或匿名函数。lambda函数的特点是&#xff1a;距离近、简洁、高效和功能强大。优点声明式编程风格&#xff1a;就地匿名定义目标函数或函数对象&#xff0c;有更好的可读性和可维护性。简洁&#xff…

webspider_20230216

下载网页源代码 分析下规则 抓取咱们需要的信息 仅限于合法的行为&#xff0c;仅仅提供自动化&#xff0c;省得手工去获取图片、手机、邮箱等信息

Spring Cloud是什么?怎么理解Spring Cloud?

简介Spring Cloud项目的官方网址&#xff1a;https://projects.spring.io/spring-cloud/ Spring Cloud 并不是一个项目&#xff0c;而是一组项目的集合。在 Spring Cloud中包含了很多的子项目&#xff0c;每一个子项目都是一种微服务开发过程中遇到的问题的一种解决方案。它利…

机场航站楼告别人工巡检,提高空间安全性

机场是现代化民航基础设施体系&#xff0c;加快数字化转型、建设更高水平的智慧城市已成为城市竞争的新赛道。图扑软件基于 HT 引擎为国内民航数字化转型支撑可视化服务提供有力的一环&#xff0c;融合物联网解决方案&#xff0c;打造适配场景的智慧机场三维可视化解决方案&…

面试题整理

面试题整理 一、Java基础 1、Java 语言有哪些特点 简单易学&#xff1b; 面向对象&#xff08;封装&#xff0c;继承&#xff0c;多态&#xff09;&#xff1b; 平台无关性&#xff08; Java 虚拟机实现平台无关性&#xff09;&#xff1b; 支持多线程&#xff08; C 语言…

#Paper Reading# Improving Language Understanding by Generative Pre-Training

论文题目: Improving Language Understanding by Generative Pre-Training 论文地址: https://www.cs.ubc.ca/~amuham01/LING530/papers/radford2018improving.pdf 论文发表于: OpenAI 2018 论文所属单位: OpenAI 论文大体内容&#xff1a; 本文主要提出了GPT&#xff08;Gene…

【SQL server】视图和索引的创建与管理

本实验数据来源课参照一下本专栏文章&#xff1a;【SQL server】进行简单查询分组、连接查询子查询和汇总&#xff08;含teaching数据库创建及实验拓展&#xff09;_Deep-sea shark的博客-CSDN博客_sql 分组汇总在SSMS中创建视图视图是一张虚表&#xff0c;数据库中只存储视图的…

关于git仓库的一些使用

配置多个ssh-key 1.生成不同的key名 如github key ssh-keygen -t rsa -C "exampleemail.com" -f ~/.ssh/github_id-rsa如gitlab key ssh-keygen -t rsa -C "examlpe企业邮箱.com" -f ~/.ssh/gitlab_id-rsa创建完成后的 macbookMacBookProdeMacBook-Pr…

STL——容器适配器、deque

一、容器适配器 1.适配器 适配器是一种设计模式&#xff08;设计模式是一套被反复使用的、多数人所知晓的、经过分类编目的、代码设计经验的总结&#xff09;&#xff0c;该种模式是将一个类的接口转换成客户希望的另外一个接口。 2.STL标准库中stack和queue的底层结构 stack…

数据结构与算法(Java版) | 就让我们来看看几个实际编程中遇到的问题吧!

上一讲&#xff0c;我给大家简单介绍了一下数据结构&#xff0c;以及数据结构与算法之间的关系&#xff0c;照理来说&#xff0c;接下来我就应该要给大家详细介绍线性结构和非线性结构了&#xff0c;但是在此之前&#xff0c;我决定还是先带着大家看几个实际编程中遇到的问题&a…

UE4 编写着色器以及各种宏的理解

参考链接&#xff1a;如何为 UE4 添加全局着色器&#xff08;Global Shaders&#xff09; - Unreal Enginehttps://docs.unrealengine.com/5.1/zh-CN/adding-global-shaders-to-unreal-engine/如何为 UE4 添加全局着色器&#xff08;Global Shaders&#xff09; - Unreal Engin…

睡眠影响寿命,这几个睡眠习惯赶紧改掉!

我们知道&#xff0c;现在睡眠不足已经成为普遍问题&#xff0c;但你知道睡眠的时长会影响寿命吗&#xff1f;熬夜对身体不好&#xff0c;已是老生常谈。但睡得过早&#xff0c;也可能影响寿命&#xff01;2021年《睡眠医学》杂志一项针对21个国家11万名参与者的研究中发现&…

重生之我是赏金猎人-SRC漏洞挖掘(十)-某大厂从废弃sso登陆口到多思路fuzz获取各地高管信息

0x01 前言 https://github.com/J0o1ey/BountyHunterInChina 欢迎亲们点个star 作者Catm78sec 前期通过灯塔 ffuf oneforall 等工具组合进行子域名收集&#xff0c;得到目标站点&#xff0c;漏洞挖掘中多次踩坑成功get腾讯某后台 0x02 渗透日常——单点登录 目标URL&…

【vcpkg】cpprestsdk之64位编译链接及踩坑

▒ 目录 ▒&#x1f6eb; 问题描述1️⃣ 多版本vs报错指定VS路径2️⃣ error LNK2001: 问题排查通过IDA打开lib文件&#xff0c;确认导出内容查看源码增加参数--editable&#xff0c;重新编译3️⃣ error LNK2001: 外部符号__imp_?close_...去除__imp_&#x1f6ec; 结论vcpkg…

浅谈估值模型:从Grinold Kroner(GK)模型看投资的本质

摘要及声明 1&#xff1a;本文主要介绍Grinold Kroner(GK)模型的运用&#xff0c;并以上证指数为例实现一个GK模型&#xff1b; 2&#xff1a;本文主要为理念的讲解&#xff0c;模型也是笔者自建&#xff0c;文中假设与观点是基于笔者对模型及数据的一孔之见&#xff0c;若有…

buffer和cache的区别

一&#xff0c;计算机硬件组成 计算机硬件组成&#xff1a;CPU&#xff0c;存储器&#xff0c;输入输出设备&#xff08;I/O&#xff09;&#xff0c;其他&#xff08;主板&#xff0c;电源等&#xff09; CPU&#xff1a;运算器&#xff0c;控制器 存储器&#xff1a;内部存储…

蓝桥云课-声网编程赛(声网编程竞赛7月专场)题解

比赛题目快速链接&#xff1a;https://www.lanqiao.cn/contests/lqENT02/challenges/ 让时钟转起来&#xff08;考点&#xff1a;css&#xff1a;transform&#xff09; // index.js function main() {// 题解前理解一个东西&#xff1a;// 时针每过一小时&#xff0c;转30 原…

博客等级说明

CSDN 博客等级是按照用户的博客积分数量进行的设定&#xff0c;为 Lv1 至 Lv10 共 10 个等级&#xff0c;不同的等级创作者可以享受到不同的权益待遇。例如&#xff0c;皮肤奖励、自定义域名、客服优先处理、自定义文章标签等特权。您需要提高博客积分进一步提升等级&#xff0…

矩阵理论复习(十二)

已知方阵A的不变因子&#xff1a; 求谱半径求矩阵级数判断矩阵幂级数的收敛性 若矩阵B的某个算子范数小于1&#xff0c;则I-B可逆。 矩阵分析 任何相容矩阵范数都存在与之相容的向量范数。 盖尔圆盘定理一的证明 椭圆范数的证明 若||.||是Cm上的向量范数&#xff0c;A为…