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

网站开发属于软件开发行业吗seo 页面链接优化

网站开发属于软件开发行业吗,seo 页面链接优化,顺德网站建设价格,常见cms网站源码下载📗线程池实现(单例模式) 1️⃣线程池概念2️⃣线程池代码样例3️⃣部分问题与细节🔸类成员函数参数列表中隐含的this指针🔸单例模式🔸一个失误导致的bug 4️⃣调用线程池完成任务 1️⃣线程池概念 线程池是…

📗线程池实现(单例模式)

  • 1️⃣线程池概念
  • 2️⃣线程池代码样例
  • 3️⃣部分问题与细节
    • 🔸类成员函数参数列表中隐含的this指针
    • 🔸单例模式
    • 🔸一个失误导致的bug
  • 4️⃣调用线程池完成任务

1️⃣线程池概念

线程池是一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量。
线程池的应用场景:

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

线程池示例:

  1. 创建固定数量线程池,循环从任务队列中获取任务对象,
  2. 获取到任务对象后,执行任务对象中的任务接口

2️⃣线程池代码样例

以下为线程池代码:

#pragma once#include <iostream>
#include <queue>
#include <pthread.h>
#include <ctime>template<class T>
class ThreadPool
{private:std::queue<T> _q;//任务队列pthread_mutex_t _lock;pthread_cond_t _cond;//有任务时提醒线程执行任务static ThreadPool<T>* _instance;ThreadPool(){}   public:static ThreadPool<T>* getInstance()//单例模式,饿汉模式,静态成员{static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;if(nullptr == _instance)//双if提高效率,因为只有第一次获取_instance时才会实例化,后续无需再加锁实例化_instance{pthread_mutex_lock(&mtx);if(nullptr == _instance){_instance = new ThreadPool<T>();}pthread_mutex_unlock(&mtx);}return _instance;}void MutexInit(){pthread_mutex_init(&_lock, nullptr);}void MutexLock(){pthread_mutex_lock(&_lock);}void MutexUnLock(){pthread_mutex_unlock(&_lock);}bool IsEmpty(){return _q.size() == 0 ? true : false;}void ThreadWait(){pthread_cond_wait(&_cond, &_lock);}void ThreadWakeUp(){pthread_cond_signal(&_cond);}void PopTask(T* out)//取任务{//此处不应加锁,应为取任务的时候是带着锁的,若此时申请锁,会出现死锁现象*out = _q.front();_q.pop();}//类内部的成员方法都有隐含的this参数,因此要加上static修饰static void* Routine(void* args){ThreadPool<T>* tp = (ThreadPool<T>*) args;//接收this指针pthread_detach(pthread_self());//线程分离while(true){tp->MutexLock();//加锁,访问临界区_qwhile(tp->IsEmpty())//任务队列为空,挂起等待{tp->ThreadWait();}//到此处说明有任务T t;tp->PopTask(&t);tp->MutexUnLock();//退出临界区_qt();}return nullptr;}void ThreadPoolInit(int num)//初始化线程池{pthread_t p[num];for(int i = 0; i < num; i++){pthread_create(p + i, nullptr, Routine, this);//将this指针作为参数传入}}void PushTask(const T& in){//分配任务MutexLock();_q.push(in);MutexUnLock();ThreadWakeUp();//唤醒线程完成任务}~ThreadPool(){pthread_mutex_destroy(&_lock);}
};template<class T>
ThreadPool<T>* ThreadPool<T>::_instance = nullptr;

3️⃣部分问题与细节

下面分享一些在编写该单例模式线程池代码遇到的一些问题与细节:

🔸类成员函数参数列表中隐含的this指针

我们在初始化线程池的这部分代码,需要创建若干线程来完成其所需要执行的任务,这些线程的例程函数形式为void *(*start_routine) (void *) ,其参数列表中仅有一个参数void*,而如果将这个例程函数定义成成员函数,会有一个隐含的this指针参数,导致形式不一致,因此需要将该例程函数用static修饰为静态的。
又因为静态成员函数只能访问静态成员变量,故我们需要在创建线程时将this指针通过参数传递给例程函数,这样才能在例程函数中使用this指针访问类中的成员变量。
在这里插入图片描述

🔸单例模式

我们这个线程池设计成了单例模式,并且采用的是饿汉模式,即服务启动后只有在用到线程池这个功能时才会创建对象。而在单例模式创建对象时,由于只有第一次创建对象时对象指针为nullptr,故判断是否要创建对象指针的时候可以在加锁之前再进行一次判断提高效率,而无需每次都要先加锁再判断。
在这里插入图片描述

🔸一个失误导致的bug

在线程取任务的接口设计时,我因为这里需要访问任务队列这个临界区给这个过程加上了锁,但是实际上在调用这个接口的时候其实线程就已经申请加了锁,而且两次申请的为同一把锁,就导致出现了线程在已经持有一把锁的情况下又去申请这把锁,从而产生了死锁。
在这里插入图片描述

4️⃣调用线程池完成任务

任务类:
实现x 与 y 的+ - * / % 五种运算。

#pragma once
#include <iostream>class Task//x op y = z
{private:int x;int y;char op;//+-*/%public:Task(){}Task(int _x, int _y, char _op):x(_x),y(_y),op(_op){}void operator()(){int z = -1;switch (op){case /* constant-expression */'+':/* code */z = x + y;break;case '-':z = x - y;break;case '*':z = x * y;break;case '/':if(0 != y)z = x / y;elsestd::cout << "warning: div zero error" << std::endl;break;case '%':if(0 != y)z = x % y;elsestd::cout << "warning: div zero error" << std::endl;break;default:std::cout << "unkonwn operator" << std::endl;break;}std::cout << "[" << pthread_self() << "] handler task: " << x << " " << op << " " << y << " = " << z << std::endl;}~Task(){}
};

主函数:

#include "thread_pool.hpp"
#include "Task.hpp"
#include <string>
#include <unistd.h>int main()
{srand((unsigned long)time(nullptr));ThreadPool<Task>* tp = ThreadPool<Task>::getInstance();tp->ThreadPoolInit(5);const std::string s = "+-*/%";while(true){int x = rand() % 50;int y = rand() % 50;char op = s[rand() % 5];Task t(x, y, op);tp->PushTask(t);sleep(1);}return 0;
}

在这里插入图片描述
结果如上,左侧为线程池中的线程每隔一秒取出任务并执行,右侧为线程池的情况。

http://www.mmbaike.com/news/30050.html

相关文章:

  • 电子商务网站建设概述深圳全网营销型网站
  • 深圳做网站报价网络营销软件大全
  • 婚礼顾问网站介绍模版网络关键词优化软件
  • 杭州地区网站公安备案最新app推广项目平台
  • 360网站备案查询百度怎么优化网站排名
  • 松山湖做网站百度左侧排名
  • 美空间网站网络推广外包加手机蛙软件
  • 青海省建设厅网站公示公告最新新闻热点事件
  • 网站微信建设运维经验分享图郑州seo技术博客
  • 办公室电脑局域网组建重庆seo整站优化外包服务
  • 花都个性设计商城网站建设新网站百度多久收录
  • 现场直播cctv5直播吧北京seo课程
  • c 网站开发连接mysql济南百度推广开户
  • 用mac做网站福州网站快速排名提升
  • 鄂州做网站公司网站推广交换链接
  • 做个网站上百度怎么做中文搜索引擎有哪些平台
  • phpwind 企业网站广东seo网站推广代运营
  • 互联网情况下做企业网站的有点长沙百度推广排名优化
  • 网站改版iis301跳转如何做爱站网长尾关键词挖掘工具电脑版
  • 做网站实际尺寸是多少南京市网站
  • 郑州的网站建设公司今日头条关键词排名优化
  • 做电商的几个网站ds2600ii色带
  • 网站建设方案说明书google官网登录入口
  • 网站里添加聊天框怎么做嘉兴seo优化
  • 中国万网网站建设服务优化大师的作用
  • 新手入门网站建设书籍快速建站平台
  • 织梦邪恶漫画网站整站源码河北seo基础入门教程
  • 金融软件网站建设公司郑州网站开发顾问
  • 做商务网站服务seo研究学院
  • 如何用excel来做网站后台谷歌排名