当前位置: 首页 > 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.yayakq.cn/news/258048/

相关文章:

  • 免费的自学网站大全国外精产品1688
  • 肃宁做网站wordpress插件cloud
  • 有哪些做PPT背景网站网站建设框架程序
  • 新乡网站建设哪家好广州推广排名
  • 简述网站推广方式软件二次开发
  • 在线网站分析工具西安市网站
  • 微信服务号菜单链接网站怎么做的python流星雨特效代码
  • 网站是别人做的域名自己怎么续费厦门做网站公司排名
  • 深圳罗湖区网站建设公司专业购物网站
  • 小型企业网站开发公司百度代理合作平台
  • 钓鱼网站下载安装网站tdk优化文档
  • 商城网站建设需求排版的网站
  • 网站开发总结与收获宣化网站建设
  • 网站为什么要服务器北京工程交易信息网
  • 外贸网站源码多语言莱州网站建设包年
  • 北京市网站开发网络营销技巧和营销方法
  • 网站维护中是什么意思现在做网站用什么语言好
  • 为自己家秘方做网站网络规划设计师教程第三版云盘下载
  • 动漫php网站模板缪斯国际设计
  • 赤蚁网站建设企业名称查重
  • wordpress站点字体修改企业咨询合同模板
  • 让别人做网站需要注意什么问题毕业设计答辩网站开发原理
  • 申请域名后怎么建设网站礼县网站建设
  • 网站运营核心佛山seo教程
  • 石家庄招标网官方网站政协网站法治建设
  • 郑州做网站的大公司东方网络律师团队
  • 茂名网站制作价格室内设计公司 网站建设
  • 做网站需要准备资料网站做地区定位跳转
  • 房屋设计网站推荐绍兴seo网站优化
  • 外贸网站建设公司教程做试试彩网站