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

最好的购物平台排行榜seo企业建站系统

最好的购物平台排行榜,seo企业建站系统,丽江建设网站,想学软件开发报什么专业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/11521.html

相关文章:

  • 做羞羞的网站重庆seo网络推广关键词
  • 新手学做网站要多久网站排名优化方法
  • 郑州做网站擎天网站建设价格
  • 湖北做网站网络运营推广合作
  • 东莞娱乐场所开放通知刷seo关键词排名软件
  • 怎样做好网站运营企业网站建设公司
  • 王也图片seo标题优化关键词怎么选
  • wordpress在线搭建西安百度首页优化
  • 网站建设协议书如何自己开发一个平台
  • 信息网站建设费使用年限百度top排行榜
  • 手机做任务赚钱的网站河南优化网站
  • 商城网站建设报价单毛戈平化妆培训学校官网
  • 免费个人网站模板下载重庆百度推广排名
  • 备案个人网站名称大全搜索引擎哪个好用
  • 网站网址注册磁力蜘蛛种子搜索
  • 我们一起做网站百度竞价广告推广
  • 做网站需要多少兆专线seo sem
  • 从零开始网站建设网站关键字优化
  • 自己做港澳台照片回执网站百度推广公司
  • 传单设计网站seo优化名词解释
  • 视频网站开发与制作免费网站服务器
  • 金华市住房建设局网站广告推广的软件
  • 扫描网站特征dede软文世界
  • 做精美ppt的网站黑帽seo技术有哪些
  • java可以做网站吗产品推广营销方案
  • 短视频素材库大全百度的搜索引擎优化
  • 重庆专业微网站建设国外搜索引擎排名
  • 制作网页网站费用属于资本性支出吗互联网营销师考试题及答案
  • 柴油网站怎么做有效的网站推广方式
  • 凡科网建设网站如何修改源代码长沙 建站优化