Webserver(5.3)线程池实现

目录

  • 线程池
  • locker.h
  • threadpool.h

线程池

相比于动态地创建子线程,选择一个已经存在的子线程的代价显然要小得多。至于主线程选择哪个子线程来为新任务服务,有多种方式:

  • 主线程使用某种算法来主动选择子线程。最简单、最常用的算法是随机算法和Round Robin(轮流选取)算法,但更优秀、更智能的算法将使任务在各个工作线程中更均匀地分配,从而减轻服务器的整体压力。
  • 主线程和所有子线程通过一个共享的工作队列来同步,子线程都睡眠在该工作队列上。当有新的任务到来时,主线程将任务添加到工作队列中。这将唤醒正在等待任务的子线程,不过只有一个子线程将获得新任务的“接管权”,它可以从工作队列中取出任务并执行之,而其他子线程将继续睡眠在工作队列上。

线程间竞争的不是CPU的计算资源而是IO,IO的处理一般较慢。
池是一组资源的集合,这组资源在服务器启动之初就被完全创建好并初始化,这称为静态资源。
当服务器执行完之后,把相关的资源放回池中,无需执行系统调用释放资源。
创建一个webserver目录
在这里插入图片描述

locker.h

#ifndef LOCKER_H
#define LOCKER_H#include<pthread.h>
#include<exception>
#include<semaphore.h>//线程同步机制封装类//互斥锁类
class locker{
public:locker(){if(pthread_mutex_init(&m_mutex,NULL)!=0){throw std::exception();}}~locker(){pthread_mutex_destroy(&m_mutex);}bool lock(){return pthread_mutex_lock(&m_mutex)==0;}bool unlock(){return pthread_mutex_unlock(&m_mutex)==0;}pthread_mutex_t * get(){return &m_mutex;}
private:pthread_mutex_t m_mutex;
};//条件变量类
class cond{
public:cond(){if(pthread_cond_init(&m_cond,NULL)!=0){throw std::exception();}}~cond(){pthread_cond_destroy(&m_cond);}bool wait(pthread_mutex_t * mutex){return pthread_cond_wait(&m_cond,mutex)==0;}bool timewait(pthread_mutex_t * mutex,struct timespec t){return pthread_cond_timedwait(&m_cond,mutex,&t)==0;}bool signal(){return pthread_cond_signal(&m_cond)==0;}bool broadcast(){return pthread_cond_broadcast(&m_cond)==0;}
private:pthread_cond_t m_cond;
};//信号量类
class sem{
public:sem(){if(sem_init(&m_sem,0,0)!=0){throw std::exception();}}sem(int num){if(sem_init(&m_sem,0,num)!=0){throw std::exception();}}~sem(){sem_destroy(&m_sem);}//等待信号量bool wait(){return sem_wait(&m_sem)==0;}//增加信号量bool post(){return sem_post(&m_sem)==0;}
private:sem_t m_sem;
};
#endif

threadpool.h

#ifndef THREADPOOL_H
#define THREADPOOL_H#include<pthread.h>
#include<list>
#include<exception>
#include<cstdio>
#include"locker.h"//线程池类,定义成模板类是为了代码的复用,模板参数T是任务类
template<typename T>
class threadpool{
public:threadpool(int thread_number=8,int max_requests=10000);~threadpool();bool append(T* request);private:static void* worker(void * arg);void run();private://线程的数量int m_thread_number;//线程池数组,大小为m_thread_numberpthread_t * m_threads;//请求队列中最多允许的,等待处理的请求数量int m_max_requests;//请求队列std::list< T*> m_workqueue;//互斥锁locker m_queuelocker;//信号量用来判断是否有任务需要处理sem m_queuestat;//是否结束线程bool m_stop;
};template<typename T>
threadpool<T>::threadpool(int thread_number,int max_requests) :m_thread_number(thread_number),m_max_requests(max_requests),m_stop(false),m_threads(NULL){if((thread_number <=0)||(max_requests<=0)){throw std::exception();}m_threads=new pthread_t[m_thread_number];if(!m_threads){throw std::exception();}//创建thread_number个线程,并将它们设置为线程脱离for(int i=0;i<thread_number;i++){printf("create the %dth thread\n",i);if(pthread_create(m_threads + i,NULL,worker,this)!=0){delete [] m_threads;throw std::exception();}if(pthread_detach(m_threads[i])){delete[] m_threads;throw std::exception();}}}template<typename T>
threadpool<T>::~threadpool(){delete[] m_threads;m_stop=true;
}template<typename T>
bool threadpool<T>::append(T *request){m_queuelocker.lock();if(m_workqueue.size()>m_max_requests){m_queuelocker.unlock();return false;}m_workqueue.push_back(request);m_queuelocker.unlock();m_queuestat.post();return true;
}template<typename T>
void* threadpool<T>::worker(void *arg){threadpool * pool=(threadpool *)arg;pool->run();return pool;
}template<typename T>
void threadpool<T>::run(){while(!m_stop){m_queuestat.wait();m_queuelocker.lock();if(m_workqueue.empty()){m_queuelocker.unlock();continue;} T* request=m_workqueue.front();m_workqueue.pop_front();m_queuelocker.unlock();if(!request){continue;}request->process();}
}
#endif

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

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

相关文章

02_ElementUI

一.前端工程化 1.1 概述 前端工程化是使用软件工程的方法来单独解决前端的开发流程 中模块化、组件化、规范化、自动化的问题,其主要目的为了 提高效率和降低成本。 1.2 NodeJS的安装 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环 境&#xff0c;可以使 JavaS…

从无音响Windows 端到 有音响macOS 端实时音频传输播放

以下是从 Windows 端到 macOS 端传输音频的优化方案&#xff0c;基于上述链接中的思路进行调整&#xff1a; Windows 端操作 安装必要软件 安装 Python&#xff08;确保版本兼容且已正确配置环境变量&#xff09;。安装 PyAudio 库&#xff0c;可通过 pip install pyaudio 命令…

SpringBoot实现的企业资产管理系统

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

建筑行业智慧知识库的搭建与运用

一、引言 在建筑领域&#xff0c;知识管理是企业持续发展和提升竞争力的关键所在。智慧知识库的构建&#xff0c;不仅能够促进知识的有效传递与共享&#xff0c;还能为项目管理和决策提供有力支持。本文将重点探讨建筑行业智慧知识库构建的价值、实践路径以及需要注意的关键点…

开源 - Ideal库 - 常用时间转换扩展方法(二)

书接上回&#xff0c;我们继续来分享一些关于时间转换的常用扩展方法。 01、时间转日期时间 TimeOnly 该方式是把TimeOnly类型转为DateTime类型&#xff0c;其中日期部分使用系统当前日期&#xff0c;时间部分则使用TimeOnly&#xff0c;具体代码如下&#xff1a; //时间转日…

29.7 编译运行,读取日志配置看图

本节重点介绍 : 编译运行&#xff0c;配置采集和大盘 编译二进制 打包后编译 go build -o log2metrics main.go修改配置文件 http_addr: 0.0.0.0:8087 log_level: INFOlog_strategy:- metric_name: log_var_log_messages_level_totalmetric_help: /var/log/messages中的日…

国产化浪潮下,高科技企业如何选择合适的国产ftp软件方案?

高科技企业在数字化转型和创新发展中&#xff0c;数据资产扮演着越来越重要的角色。在研发过程中产生的实验数据、设计文档、测试结果等&#xff0c;专利、商标、版权之类的创新成果等&#xff0c;随着信息量急剧增加和安全威胁的复杂化&#xff0c;传统的FTP软件已经不能满足这…

SQL EXISTS谓词

谓词时返回值为真值&#xff08;true、false或unknown&#xff09;的函数。EXISTS与其他谓词不同&#xff0c;它接受的参数是行的集合。 输入值为一行的谓词叫做“一阶谓词”&#xff08;例如>、<、 及 LIKE等&#xff09;&#xff1b;输入值为行的集合的谓词叫做“二阶…

[产品管理-59]:项目组合中产品或项目的类型分类: 平台类、支持改进类、衍生类、突破类

目录 一、概述 1、平台型项目&#xff1a;平台产品 2、支持性项目&#xff1a;现有产品的改进&#xff0c;还是现有产品&#xff0c;只不过性能、效率提升。 3、衍生型项目&#xff1a;衍生出来的新产品&#xff0c;不同于现有产品&#xff0c;但与现有产品有关联 4、突破…

Jmeter的安装和使用

使用场景&#xff1a; 我们需要对某个接口进行压力测试&#xff0c;在多线程环境下&#xff0c;服务的抗压能力&#xff1b;还有就是关于分布式开发需要测试多线程环境下数据的唯一性。 解决方案: jmeter官网连接&#xff1a;Apache JMeter - Apache JMeter™ 下载安装包 配…

一文学习Android中的Property

在 Android 系统中&#xff0c;Property 是一种全局的键值对存储系统&#xff0c;允许不同组件和进程间以轻量级的方式进行数据传递。它主要用于系统配置、状态标识等场景&#xff0c;使得不同进程能够通过属性的设置或获取来通信。property 的核心特性是快速、高效&#xff0…

aosp15系统窗口闪屏原生bug-dim图层相关-你会修改吗?

背景 近期各个大厂已经开始准备aosp15的系统rom适配工作了&#xff0c;应该是想2025年初开发发布相关的新机型&#xff0c;所以慢慢的我们也要开始适应aosp15版本的相关问题的修改和研究哈。 近期就有相关学员朋友在做android15相关的dialog开发时候&#xff0c;发现了一个严…

SCUI Admin + Laravel 整合

基于 Vue3 和 Element Plus 和 Laravel 整合开发 项目地址&#xff1a;持续更新 LaravelVueProject: laravel vue3 scui

LeetCode 热题 100之 堆

1.数组中第k个最大元素 和Acwing 786 第k个数一模一样 排序 思路分析1&#xff1a;此题要求时间复杂度未为O(n)。虽然库函数sort和快速排序都能过&#xff0c;但是时间复杂度不满足条件。下面优化快速排序&#xff0c;写一个快速选择算法。我们可以引入随机化来加速这个过程&…

使用SpringBoot+Vue+Echarts制作一个文章贡献度表

使用SpringBootVueEcharts制作一个文章贡献度表 制作博客贡献表 使用了ECharts中的 calendar-effectscatter 组件制作贡献表&#xff1a;点我传送 首先附上完整的vue代码&#xff1a; <template><div id"container" style" width: 100%; height: 30…

使用Matlab建立决策树

综述 除了神经网络模型以外&#xff0c;树模型及基于树的集成学习模型是较为常用的效果较好的预测模型。我们以下先构建一个决策树模型。 决策树算法的优点如下&#xff1a;1、 决策树易于理解和实现&#xff0c;用户在学习过程中不需要了解过多的背景知识&#xff0c;其能够…

LangGPT结构化提示词编写实践

基础任务 如果直接询问大模型strawberry有几个r&#xff0c;大模型会给出错误的答案&#xff1a; 这里我们引入思维连Chain of Thought&#xff0c;我们让大模型遍历一遍单词&#xff0c;每次累加得到最终结果 之前怎么都做不对的题&#xff0c;让大模型一步一步思考&#xf…

开源ISP(Infinite-ISP)介绍

ISP&#xff08;Image Signal Processor&#xff09;我介绍了很多了&#xff0c;大家可以先看下面的文章&#xff0c;了解基本概念&#xff1a; ISP算法及架构分析介绍 谈谈FPGA工程师如何做ISP 图像信号处理器和 Infinite-ISP ISP从图像传感器获取 RAW 像素&#xff0c;并将其…

如何在c++侧编译运行一个aclnn(AOL)算子?

1 AOL算子库 CANN&#xff08;Compute Architecture for Neural Networks&#xff09;提供了算子加速库&#xff08;Ascend Operator Library&#xff0c;简称AOL&#xff09;。该库提供了一系列丰富且深度优化过的高性能算子API&#xff0c;更亲和昇腾AI处理器&#xff0c;调…

三分钟学会Docker基本操作,快速入门容器技术!

如果您时常遭遇以下困境&#xff1a; 被繁琐的应用安装依赖与环境配置耗尽了宝贵时间与精力&#xff1f; 即便严格遵循安装指南&#xff0c;仍频遇障碍&#xff0c;导致应用无法启动&#xff0c;让您倍感挫败与焦虑&#xff1f; 向研发团队反馈安装难题&#xff0c;却只换来“…