当前位置: 首页 > wzjs >正文

企业网站排名提升软件智能优化宁波seo网络推广优化价格

企业网站排名提升软件智能优化,宁波seo网络推广优化价格,网站建设论文html格式,vue.js网站开发用例目录 Linux线程池 线程池的概念 线程池的优点 线程池的应用场景 线程池的实现 Linux线程池 线程池的概念 线程池是一种线程的使用模式。 其存在的主要原因就为:线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程&#…

目录

Linux线程池

线程池的概念

线程池的优点

线程池的应用场景

线程池的实现


Linux线程池

线程池的概念

线程池是一种线程的使用模式。

其存在的主要原因就为:线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。

线程池的优点

  1. 线程池避免了再处理短时间任务时创建于销毁线程的代价。
  2. 线程池不仅能够保证内核的充分利用,还能防止过分调度。 

注意:线程池可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量。

线程池的应用场景

线程池常见的应用场景如下:

  1. 需要大量的线程来完成任务,且完成任务的时间比较短。
  2. 对性能要求苛刻的应用,比如要求服务器迅速响应客户请求。
  3. 接受突发性的大量请求,但不至于使服务器因此产生大量线程的应用。

相关现实场景应用:

  1. WEB服务器完成网页请求这样的任务,使用线程池技术是非常合适的。因为单个任务小,而任务数量巨大,你可以想象一个热门网站的点击次数。
  2. 但对于长时间的任务,比如一个Telnet连接请求,线程池的优点就不明显了。因为Telnet会话时间比线程的创建时间大多了。
  3. 突发性大量客户请求,在没有线程池情况下,将产生大量线程,虽然理论上大部分操作系统线程数目最大值不是问题,短时间内产生大量线程可能使内存到达极限,出现错误.

线程池的实现

下面我们用图示,表达一个简单的线程池,线程池中提供了一个任务队列,以及若干个线程(多线程)。

  • 线程池中的多个线程负责从任务队列当中拿任务,并将拿到的任务进行处理。
  • 线程池对外提供一个Push接口,用于让外部线程能够将任务Push到任务队列当中。

线程池的代码如下:

.hpp  (ThreadPool.hpp)

#include <iostream>
#include <unistd.h>
#include <queue>
#include <stdlib.h>
#include <pthread.h>class ThreadInfo
{
public:pthread_t tid_;std::string name_;
};static const int defalutnum = 5;template <class T>
class ThreadPool
{
public:void Lock(){pthread_mutex_lock(&mutex_);}void Unlock(){pthread_mutex_unlock(&mutex_);}void Wakeup(){pthread_cond_signal(&cond_);}void ThreadSleep(){pthread_cond_wait(&cond_, &mutex_);}bool IsQueueEmpty(){return tasks_.empty();}std::string GetThreadName(pthread_t tid){for(const auto& ti:threads_){if(ti.tid_ == tid){return ti.name_;}}return "None";}
public:static void *HandlerTask(void *args) // 带 static 是因为类内的函数第一个参数是默认为 this 指针{ThreadPool<T> *tp = static_cast<ThreadPool*>(args);std::string name = tp->GetThreadName(pthread_self());while(true){tp->Lock();while(tp->IsQueueEmpty()){tp->ThreadSleep();}// 分配到任务T t = tp->Pop();std::cout<< 分配到了一个任务 : " << t << "," << name << "run" << std::endl;tp->Unlock();sleep(1);// 后续的任务处理部分// run();}}void Start(){int num = defalutnum;for(int i=0; i < num; i++){threads_[i].name_ = "thread-" + std::to_string(i + 1);pthread_create(&(threads_[i].tid_), nullptr, HandlerTask, this);}}T Pop(){T t = tasks_.front();tasks_.pop();return t;}void Push(const T &t){Lock();tasks_.push(t);Wakeup();Unlock();}
public:ThreadPool(int num = defalutnum) :threads_(num){pthread_mutex_init(&mutex_, nullptr);pthread_cond_init(&cond_, nullptr);}~ThreadPool(){pthread_mutex_destroy(&mutex_);pthread_cond_destroy(&cond_);}
private:std::vector<ThreadInfo> threads_;std::queue<T> tasks_;pthread_mutex_t mutex_;pthread_cond_t cond_;
};

知识回顾:为什么线程池中需要有互斥锁和条件变量?

因为线程池中的任务队列是会被多个执行流同时访问的临界资源,因此为了避免数据二义性,就会创建互斥锁与条件变量来进行保护。

线程池当中的线程要从任务队列里拿任务,前提条件是任务队列中必须要有任务,因此线程池当中的线程在拿任务之前,需要先判断任务队列当中是否有任务,若此时任务队列为空,那么该线程应该进行等待,直到任务队列中有任务时再将其唤醒,因此我们需要引入条件变量。

当外部线程向任务队列中Push一个任务后,此时可能有线程正处于等待状态,因此在新增任务后需要唤醒在条件变量下等待的线程。

注意:

  • 当某线程被唤醒时,其可能是被异常或是伪唤醒,或者是一些广播类的唤醒线程操作而导致所有线程被唤醒,使得在被唤醒的若干线程中,只有个别线程能拿到任务。此时应该让被唤醒的线程再次判断是否满足被唤醒条件,所以在判断任务队列是否为空时,应该使用while进行判断,而不是if。
  • 这里的唤醒是用的pthread_cond_signal而不是pthread_cond_broadcast,那是因为,如果外部向队列中push了一个任务,但我们却使用pthread_cond_broadcast,将所有的等待线程全部唤醒,但实际情况却仅需要一个线程,那这肯定会资源的浪费。一瞬间唤醒大量的线程可能会导致系统震荡,这叫做惊群效应。所以在唤醒线程时最好还是使用pthread_cond_signal函数唤醒一个正在等待的线程即可。
  • 当线程从任务队列中拿到任务后,该任务就已经属于当前线程了,与其他线程已经没有关系了。因此应该在解锁之后再进行处理任务,而不是在解锁之前进行。因为处理任务的过程可能会耗费一定的时间,所以我们不要将其放到临界区当中。
  • 还有就是设计的效率问题,如果我们将处理任务的操作也放在临界区来处理,那么当某一线程从任务队列中拿到任务后,其他线程还需要等待该线程将任务处理完后,才有机会进入临界区。这样的设计虽然也叫做线程池,但显然效率是远没有仅仅将拿取任务部分放在临界区的效率高。

 为什么线程池中的线程执行例程需要设置为静态方法?

使用pthread_create函数创建线程时,需要为创建的线程传入一个HandlerTask(执行例程),该HandlerTask只有一个参数类型为void*的参数,以及返回类型为void*的返回值。

而此时HandlerTask作为类的成员函数,该函数的第一个参数是隐藏的this指针,因此这里的HandlerTask函数,虽然看起来只有一个参数,而实际上它有两个参数,此时直接将该HandlerTask函数作为创建线程时的执行例程是不行的,无法通过编译。

静态成员函数属于类,而不属于某个对象,也就是说静态成员函数是没有隐藏的this指针的,因此我们需要将HandlerTask设置为静态方法,此时HandlerTask函数才真正只有一个参数类型为void*的参数。

但是在静态成员函数内部无法调用非静态成员函数,而我们需要在HandlerTask函数当中调用该类的某些非静态成员函数,比如Pop。因此我们需要在创建线程时,向Routine函数传入的当前对象的this指针,此时我们就能够通过该this指针在HandlerTask函数内部调用非静态成员函数了。

 主函数:.cpp  (proc.cc)

#include <iostream>
#include <ctime>
#include "ThreadPool.hpp"int main()
{std::cout << "process running..." << std::endl;sleep(3);ThreadPool<int> *tp = new ThreadPool<int>();tp->Start();srand(time(nullptr) ^ getpid());while(true){//1. 构建任务int x = rand() % 10 + 1;tp->Push(x);//2. 交给线程池处理std::cout << "proc thread make task: " << std::endl;sleep(1);}
}

 makefile

Threadpool:proc.ccg++ -o $@ $^ -std=c++11 -lpthread
.PHONY:clean
clean:rm -f Threadpool

 运行效果如下:

http://www.dtcms.com/wzjs/517145.html

相关文章:

  • 新能源汽车十大名牌上海最专业的seo公司
  • 网页设计制作导航栏优化网站建设seo
  • 凤凰县政府网站建设优化大师win10能用吗
  • 自发购卡网站在吗做山东济南最新事件
  • 做网站电销清远头条新闻
  • 做企业网站还有钱挣吗搜索引擎整合营销
  • 个人做的网站有什么危险大数据培训
  • 中国建设银行舟山分行网站衡水网站优化推广
  • 北京 建设工程 质监站网站做网站用哪个软件
  • 重庆网站建站产品推广网站
  • 如何注册免费网站免费网站自助建站系统
  • 长春网站制作哪里好百度一下官网首页百度
  • 找网站设计公司今日新闻摘抄十条
  • 网站建设毕业设计国家免费职业技能培训官网
  • 网页框架代码怎么做百度关键词优化查询
  • 青岛建网站公司长沙网站推广和优化
  • 包头有没有专业做淘宝网站的惠州seo关键词推广
  • 宠物网站设计的代码市场营销策划公司
  • 大连网站哪家做的好排名首页服务热线
  • 即便你卖的是网站优化就是搜索引擎优化
  • 万域网站建设网络营销的方式与手段
  • 河南工程建设信息网站冯耀宗seo视频教程
  • 今天最新消息优化系统
  • 云南省城乡与住房建设厅网站友情链接联盟
  • 社区网站设计策划书3000字济源新站seo关键词排名推广
  • 网站制作协议书营销软件排名
  • 网站代理备案百度网址大全官方网站
  • 建设手机网站赚钱吗销售管理软件
  • 长沙网站运营外包公司全国疫情高峰感染高峰
  • 做网站建设推广好做吗新闻发布最新新闻