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

平度那里有做网站的百度关键词刷排名软件

平度那里有做网站的,百度关键词刷排名软件,泉州市做网站优化,容易导致网站作弊的几个嫌疑线程池的概念 线程池是一种线程使用模式。 一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。…

线程池的概念                                                              

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

一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。

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

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

线程池的应用场景

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

线程池的实现

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

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

线程池代码如下:

#include <iostream>
#include <pthread.h>
#include <vector>
#include <queue>
#include <string>static const int defaultnum = 5;struct ThreadInfo
{pthread_t tids;std::string NameThread;
};template<class T>
class ThreadPool
{
public:void Lock(){pthread_mutex_lock(&lock);}void UnLock(){pthread_mutex_unlock(&lock);}void Wait(){pthread_cond_wait(&cond, &lock);}void WakeUp(){pthread_cond_signal(&cond);}bool IsEmptyTask(){return _TasksQueue.size() == 0;}public:ThreadPool(int num = defaultnum): _threads(num){pthread_mutex_init(&lock, nullptr);pthread_cond_init(&cond, nullptr);}void ThreadStart(){int n = _threads.size();for(int i = 0; i < n; i++){pthread_create(&_threads[i].tids, nullptr, ThreadTasks, this);_threads[i].NameThread = "thread-" + std::to_string(i);}}std::string GetThreadName(pthread_t tid){for(auto& e : _threads){if(tid == e.tids){return e.NameThread; }}return "none";}static void *ThreadTasks(void* args){ThreadPool<T>* TP = static_cast<ThreadPool<T>*>(args);while(true){std::string Name = TP->GetThreadName(pthread_self());TP->Lock();while(TP->IsEmptyTask()){TP->Wait();}T t = TP->pop();TP->UnLock();t();std::cout << Name.c_str() << ' ' << std::endl;t.GetTask();}}T pop(){T t = _TasksQueue.front();_TasksQueue.pop();return t;}void push(const T &task){Lock();_TasksQueue.push(task);WakeUp();UnLock();}~ThreadPool(){pthread_mutex_destroy(&lock);pthread_cond_destroy(&cond);}
private:std::vector<ThreadInfo> _threads;std::queue<T> _TasksQueue;pthread_mutex_t lock;pthread_cond_t cond;
};

为什么线程池中需要有互斥锁和条件变量?

使用互斥锁的原因:STL容器一开始被设计时,就是为了追求效率,并没有考虑线程安全,多线程场景,pop数据时可能产生并发问题

使用条件变量的原因:

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

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

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

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

任务类型的设计

#pragma once#include "ThreadPool.hpp"enum
{EXITCODE = 0,DIVZERO,MODZERO
};class Task
{
public:Task(int x, int y, char oper, int exitcode_ = EXITCODE) : _data1(x), _data2(y), _oper(oper), exitcode(exitcode_){}void run(){switch (_oper){case '+':result = _data1 + _data2;break;case '-':result = _data1 - _data2;break;case '*':result = _data1 * _data2;break;case '/':if(_data1 == 0 | _data2 == 0){exitcode = DIVZERO;}else{result = _data1 / _data2;}break;case '%':if(_data1 == 0 | _data2 == 0){exitcode = MODZERO;}else{result = _data1 % _data2;}break;default:std::cout << "Symbol mismatch!" << std::endl;break;}SolveTask();}std::string _To_String(){std::string str;str += "[exitcode: ";str += std::to_string(exitcode);str += "]";str += " ";str += std::to_string(_data1);str += " ";str += _oper;str += " ";str += std::to_string(_data2);return str;}void GetTask(){std::cout << _data1 << " " << _oper << " " << _data2 << " = ?" << std::endl;}void SolveTask(){std::cout << _To_String() << " = " << result << std::endl;}void operator()(){run();}~Task(){}private:int _data1;int _data2;char _oper;int exitcode;int result;
};

主线程逻辑

主线程就负责不断向任务队列当中Push任务就行了,此后线程池当中的线程会从任务队列当中获取到这些任务并进行处理。

#include "SingletonThreadPool.hpp"
#include "Task.hpp"
#include <unistd.h>std::string oper = "+-*/%";int main()
{srand(time(nullptr));SingletonThreadPool<Task>* STP = new SingletonThreadPool<Task>(5);STP->ThreadStart();int len = oper.size(); while(true){sleep(1);int data1 = rand() % 10;int data2 = rand() % 10 + 1;char op = oper[rand() % len];Task t(data1, data2, op);t.push(t);t.GetTask();}return 0;
}

运行代码后一瞬间就有六个线程,其中一个是主线程,另外五个是线程池内处理任务的线程。

注意: 此后我们如果想让线程池处理其他不同的任务请求时,我们只需要提供一个任务类,在该任务类当中提供对应的任务处理方法就行了。

线程安全的单例模式

什么是单例模式

单例模式是一种 "经典的, 常用的, 常考的" 设计模式.

什么是设计模式

IT行业这么火, 涌入的人很多. 俗话说林子大了啥鸟都有. 大佬和菜鸡们两极分化的越来越严重. 为了让菜鸡们不太拖大佬的后腿, 于是大佬们针对一些经典的常见的场景, 给定了一些对应的解决方案, 这个就是 设计模式

单例模式的特点

某些类, 只应该具有一个对象(实例), 就称之为单例. 在很多服务器开发场景中, 经常需要让服务器加载很多的数据 (上百G) 到内存中. 此时往往要用一个单例的类来管理这些数据.

饿汉实现方式和懒汉实现方式

饿汉方式就是直接在类中将需要使用的对象先申请好

懒汉方式最核心的思想是 "延时加载". 从而能够优化服务器的启动速度.

例如:

#pragma onceclass Singleton
{
public:Singleton(){std::cout << "对象创建成功" << std::endl;}static Singleton& GetInstance(){return num;}private:static Singleton num;
};
#include <iostream>using namespace std;
#include "singleton.hpp"//static int num = 10;Singleton init1;
Singleton init2;
Singleton init3;
Singleton init4;
Singleton init5;
Singleton init6;int main()
{printf("启动!!!\n");    return 0;
}

可以看到饿汉式的单例模式会在程序启动之前对象就创建好了

饿汉方式实现单例模式

template <typename T> class Singleton 
{static T data;
public:static T* GetInstance() {return &data;} 
};

只要通过 Singleton 这个包装类来使用 T 对象, 则一个进程中只有一个 T 对象的实例

懒汉方式实现单例模式

template <typename T> class Singleton
{static T* inst; 
public:static T* GetInstance() {if(inst == NULL) {inst = new T();}return inst;} 
};

存在一个严重的问题, 线程不安全.
第一次调用 GetInstance 的时候, 如果两个线程同时调用, 可能会创建出两份 T 对象的实例.

懒汉方式实现单例模式(线程安全版本)

// 懒汉模式, 线程安全 
template <typename T> 
class Singleton { volatile static T* inst;  // 需要设置 volatile 关键字, 否则可能被编译器优化. static std::mutex lock; 
public: static T* GetInstance(){ if(inst == NULL)  //避免占用CPU和操作系统资源,做无意义的事,提高效率{  lock.lock();          // 使用互斥锁, 保证多线程情况下也只调用一次 new.if (inst == NULL) { inst = new T(); } lock.unlock(); } return inst; } 
}; 

注意事项:

1. 加锁解锁的位置

2. 双重 if 判定, 避免不必要的锁竞争

3. volatile关键字防止过度优化

将上述线程池代码改为单例模式

#pragma once#include <iostream>
#include <pthread.h>
#include <queue>
#include <vector>
#include <string>static const int defaultnum = 5;class ThreadInfo
{
public:pthread_t tid;std::string threadname;
};template <class T>
class SingletonThreadPool
{void Lock(){pthread_mutex_lock(&lock);}void UnLock(){pthread_mutex_unlock(&lock);}void Wait(){pthread_cond_wait(&cond, &lock);}void WakeUp(){pthread_cond_signal(&cond);}bool IsEmptyThreadPool(){return _tasksqueue.size() == 0;}public:static void* RoutineTasks(void* args){SingletonThreadPool<T> *TP = static_cast<SingletonThreadPool<T>*>(args);while(true){std::string name = TP->GetThreadName(pthread_self());TP->Lock();if(TP->IsEmptyThreadPool()){TP->Wait();}T t = TP->pop();TP->UnLock();t();std::cout << name << ' ' << std::endl;t.GetTask();}}public:void ThreadStart(){int num = _threads.size();for(int i = 0; i < num; i++){pthread_create(&_threads[i].tid, nullptr, RoutineTasks, this);_threads[i].threadname = "thread-" + std::to_string(i);}}T pop(){T task = _tasksqueue.front();_tasksqueue.pop();return task;}std::string GetThreadName(pthread_t tid){for(const auto& e : _threads){if(tid == e.tid)return e.threadname;}return "none";}void push(const T& task){Lock();_tasksqueue.push(task);WakeUp();UnLock();}static SingletonThreadPool<T>* GetInStance(){//避免占用CPU和操作系统资源,做无意义的事,提高效率if(inst == nullptr){//避免多线程模式下,同时申请多个instpthread_mutex_lock(&slock);if(inst == nullptr){inst = new SingletonThreadPool<T>;}pthread_mutex_unlock(&slock);}return inst;}private:SingletonThreadPool(int num = defaultnum):_threads(num){pthread_mutex_init(&lock, nullptr);pthread_cond_init(&cond, nullptr);}~SingletonThreadPool(){pthread_mutex_destroy(&lock);pthread_cond_destroy(&cond);}//防拷贝SingletonThreadPool(const SingletonThreadPool<T>& STP) = delete;SingletonThreadPool<T>& operator=(const SingletonThreadPool<T>& STP) = delete;private:std::vector<ThreadInfo> _threads;std::queue<T> _tasksqueue;pthread_mutex_t lock;pthread_cond_t cond;static SingletonThreadPool<T> *inst;static pthread_mutex_t slock;
}; template<class T>
SingletonThreadPool<T>* SingletonThreadPool<T>::inst = nullptr;template<class T>
pthread_mutex_t SingletonThreadPool<T>::slock = PTHREAD_MUTEX_INITIALIZER;
#include "SingletonThreadPool.hpp"
#include "Task.hpp"
#include <unistd.h>std::string oper = "+-*/%";int main()
{srand(time(nullptr));SingletonThreadPool<Task>::GetInStance()->ThreadStart();int len = oper.size(); while(true){sleep(1);int data1 = rand() % 10;int data2 = rand() % 10 + 1;char op = oper[rand() % len];Task t(data1, data2, op);SingletonThreadPool<Task>::GetInStance()->push(t);t.GetTask();}return 0;
}
http://www.dtcms.com/wzjs/144341.html

相关文章:

  • 淘宝客优惠卷网站模板提高工作效率的软件
  • 做一个商城网站需要提交那些文件seo百科大全
  • 装修公司做推广网站怎么弄网站优化塔山双喜
  • 做网站从何开始最近的新闻大事20条
  • 东莞做企业网站友情下载网站
  • 七里港网站建设互联网推广渠道有哪些
  • 外链的论坛网站站长统计幸福宝下载
  • 佛山外贸网站制作公司最新军事报道
  • 电白网站开发公司网站推广优化教程
  • 有了云服务器怎么做网站百度服务中心电话
  • 购物网站及app开发黄冈seo顾问
  • 百度seo排名点击seo推广营销靠谱
  • 官方网站开发商seo的方式包括
  • php网站开发建设seo关键词怎么选
  • 辽阳做网站的公司微信朋友圈推广软文
  • 长春高铁站桂林seo排名
  • 网站权重传递北京网站优化推广方案
  • phpwind能做网站吗网站内部优化有哪些内容
  • b2b网站产品群发工具百度广告点击软件
  • 用群晖做网站服务器小型项目外包网站
  • 学剪辑有必要报班吗怎么样关键词优化
  • 太原市建设银行网站首页抖音seo培训
  • 做门户网站用什么服务器百度推广费用怎么算
  • 怎么做淘宝客手机网站推广百度搜索风云榜
  • 内蒙古网站建设网络策划是做什么的
  • 网站建设管理中se是什么意思深圳最新政策消息
  • 做网站需要开放哪些端口seo搜索引擎优化推广专员
  • 注册小微公司流程及费用优化seo厂家
  • 做网站怎么维护东莞网站seo公司哪家大
  • 温州龙湾做网站公司产品怎样网上推广