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

动态网站欣赏搜索广告是什么

动态网站欣赏,搜索广告是什么,龙岩网红景点,新闻类的网站如何做优化、1.线程池 线程池是由服务器预先创建的一组子线程,线程池中的线程数量应该和 CPU 数量差不多。线程池中的所有子线程都运行着相同的代码。当有新的任务到来时,主线程将通过某种方式选择线程池中的某一个子线程来为之服务。相比与动态的创建子线程&#x…

1.线程池

线程池是由服务器预先创建的一组子线程,线程池中的线程数量应该和 CPU 数量差不多线程池中的所有子线程都运行着相同的代码。当有新的任务到来时,主线程将通过某种方式选择线程池中的某一个子线程来为之服务。相比与动态的创建子线程,选择一个已经存在的子线程的代价显然要小得多。至于主线程选择哪个子线程来为新任务服务,则有多种方式:

① 主线程使用某种算法来主动选择子线程。最简单、最常用的算法是随机算法和 Round Robin(轮流选取)算法,但更优秀、更智能的算法将使任务在各个工作线程中更均匀地分配,从而减轻服务器 的整体压力。

② 主线程和所有子线程通过一个共享的工作队列来同步,子线程都睡眠在该工作队列上。当有新的任务到来时,主线程将任务添加到工作队列中。这将唤醒正在等待任务的子线程,不过只有一个子线程将获得新任务的”接管权“,它可以从工作队列中取出任务并执行之,而其他子线程将继续睡眠在工作队列上。

线程池中的线程数量最直接的限制因素是中央处理器(CPU)的处理器(processors/cores)的数量N :如果你的CPU是4-cores的,对于CPU密集型的任务(如视频剪辑等消耗CPU计算资源的任务)来说,那线程池中的线程数量最好也设置为4(或者+1防止其他因素造成的线程阻塞);对于IO密集型的任务,一般要多于CPU的核数,因为线程间竞争的不是CPU的计算资源而是IO,IO的处理一般较慢,多于cores数的线程将为CPU争取更多的任务,不至在线程处理IO的过程造成CPU空闲导致资源浪费。

  • 空间换时间,浪费服务器的硬件资源,换取运行效率。
  • 池是一组资源的集合,这组资源在服务器启动之初就被完全创建好并初始化,这称为静态资源。
  • 当服务器进入正式运行阶段,开始处理客户请求的时候,如果它需要相关的资源,可以直接从池中获取,无需动态分配。
  • 当服务器处理完一个客户连接后,可以把相关的资源放回池中,无需执行系统调用释放资源。

1.1 线程池类定义

// 线程池类,将它定义为模板类是为了代码复用,模板参数T是任务类
template<typename T>
class threadpool {
public:/*thread_number是线程池中线程的数量,max_requests是请求队列中最多允许的、等待处理的请求的数量*/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_number    pthread_t * m_threads;// 请求队列中最多允许的、等待处理的请求的数量  int m_max_requests; // 请求队列std::list< T* > m_workqueue;  // 保护请求队列的互斥锁locker m_queuelocker;   // 是否有任务需要处理sem m_queuestat;// 是否结束线程          bool m_stop;                    
};

1.2 线程池创建与回收

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();}// 线程id初始化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;
}

1.3 向请求队列中添加任务

通过list容器创建请求队列,向队列中添加任务时,通知互斥锁保证线程安全,添加完成后通过信号量提醒有任务要处理,最后注意线程同步。

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;
}

1.4 线程处理函数

内部访问私有成员函数run,完成线程处理

template< typename T >
void* threadpool< T >::worker( void* arg )
{// 将参数强转为线程池类,调用成员方法threadpool* pool = ( threadpool* )arg;pool->run();return pool;
}

1.5 run执行任务

主要实现,工作线程从请求队列中取出某个任务进行处理,注意线程同步 

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;}// process(模板类中的方法,这里是http类)进行处理request->process();}}

1.6 注意事项【总结来源两猿社的最新版Web服务器项目详解 - 03 半同步半反应堆线程池(下)】

pthread_create的函数原型

#include <pthread.h>
int pthread_create (pthread_t *thread_tid,//返回新生成的线程的idconst pthread_attr_t *attr,//指向线程属性的指针,通常设置为NULLvoid * (*start_routine) (void *),//处理线程函数的地址void *arg);//start_routine()中的参数

在 pthread_create函数原型中的第三个参数,为函数指针,指向处理线程函数的地址。且该函数为静态函数,所以在处理线程函数为类成员函数时,需要将其设置为静态成员函数。

// 线程池类,将它定义为模板类是为了代码复用,模板参数T是任务类
template<typename T>
class threadpool {
private:/*工作线程运行的函数,它不断从工作队列中取出任务并执行之*/static void* worker(void* arg);
public:...
};

【原因】

  • pthread_create的函数原型中的第三个参数的类型为函数指针,指向的线程处理函数参数类型为(void *)。
  • 线程函数若为类成员函数,则this指针会作为默认参数被传进函数中,无法和线程函数参数(void *)匹配,无法编译。
  • 由于静态成员函数里面没有this指针,能解决线程函数参数(void*)匹配问题。

完整代码:

threadpool.h

#ifndef THREADPOOL_H
#define THREADPOOL_H#include <list>
#include <cstdio>
#include <exception>
#include <pthread.h>
#include "locker.h"// 线程池类,将它定义为模板类是为了代码复用,模板参数T是任务类
template<typename T>
class threadpool {
public:/*thread_number是线程池中线程的数量,max_requests是请求队列中最多允许的、等待处理的请求的数量*/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_number    pthread_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

locker.h

​
#ifndef LOCKER_H
#define LOCKER_H#include <exception>
#include <pthread.h>
#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 *m_mutex) {int ret = 0;ret = pthread_cond_wait(&m_cond, m_mutex);return ret == 0;}bool timewait(pthread_mutex_t *m_mutex, struct timespec t) {int ret = 0;ret = pthread_cond_timedwait(&m_cond, m_mutex, &t);return ret == 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​
http://www.hrbkazy.com/news/9989.html

相关文章:

  • 如何做二维码链接网站搜索引擎营销的手段包括
  • 南山企业网站建设女装关键词排名
  • 绵阳建网站哪家好西安网络优化哪家好
  • 怎么查询商标是否已被注册宁波seo网站
  • 连云港网站建设价格公司网站域名怎么注册
  • 口碑好的网站建设公司哪家好全网推广系统
  • 以色列网站后缀批量关键词调排名软件
  • 深圳中小企业网站制作网页制作作业100例
  • 东莞网页网站制作美国搜索引擎排名
  • 做网站的那些个人工作室公关团队
  • 网站推广的最终目的是什么推广软件赚钱的app
  • 渭南做网站哪家公司免费发布信息平台有哪些
  • 外贸中间体做哪个网站好烟台seo关键词排名
  • 给人做网站赚钱网站快速收录软件
  • 不同国家访问wordpress web 显示不用语言seo优化排名
  • 做网站税点百度指数排名
  • 郑州华恩科技做网站怎么样怎么做公司网站
  • 珠海政府网站建设公司宁波seo搜索优化费用
  • 网站服务公司官网seo深圳网络推广
  • 企业1级域名网站怎么做品牌广告
  • mac 做网站seo入门
  • 做酒店经理的一些网站网站备案是什么意思
  • 网站开发规格网站域名ip地址查询
  • 怎样做好外贸网站推广网络营销产品的特点
  • 诸城个人网站建设游戏推广赚佣金
  • 深圳建设局网站首页怎么做互联网推广
  • 如何将网站挂载域名郑州seo使用教程
  • 网络营销导向企业网站建设的一般原则北京网站建设制作公司
  • 在俄罗斯用钱让女性做h事情的网站平台推广方式
  • 企业建设网站能否报销点击排名优化