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

怎么低成本做网站国内好用的搜索引擎

怎么低成本做网站,国内好用的搜索引擎,ih5网页制作教程,做网站 发现对方传销目录 一、线程池实现原理 二、定义线程池的结构 三、创建线程池实例 四、添加工作的线程的任务函数 五、管理者线程的任务函数 六、往线程池中添加任务 七、获取线程池工作的线程数量与活着的线程数量 八、线程池的销毁 一、线程池实现原理 线程池的组成主要分为3个部…

目录

一、线程池实现原理

二、定义线程池的结构

三、创建线程池实例

四、添加工作的线程的任务函数

五、管理者线程的任务函数

六、往线程池中添加任务

七、获取线程池工作的线程数量与活着的线程数量

八、线程池的销毁


一、线程池实现原理

线程池的组成主要分为3个部分。这三部分配合工作就可以得到一个完整的线程池:

1、任务队列,存储需要处理的任务。由工作的想程来处理这些任务

  • 通过线程池提供的API函数,将一个待处理的任务添加到任务队列,或者从任务队列中删除
  • 已处理的任务会被从任务队列中删除
  • 线程池的使用者,也就是调用线程池函数往任务队列中添加任务的线程就是生产者线程

2、工作的线程 (任务队列任务的消费者),N个

  • 线程池中维护了一定数量的工作线程,他们的作用是不停的读任务队列,从里边取出任务并处理
  • 工作的线程相当于是任务队列的消费者角色
  • 如果任务队列为空,工作的线程将会被阻塞(使用条件变量/信号量阻塞)
  • 如果阻塞之后有了新的任务,由生产者将阻塞解除,工作线程开始工作

3、管理者线程(不处理任务队列中的任务),1个

  • 它的任务是周期性的对任务队列中的任务数量以及处于忙状态的工作线程个数进行检测

          ——当任务过多的时候,可以适当的创建一些新的工作线程

          ——当任务过少的时候,可以适当的销毁一些工作的线程

二、定义线程池的结构

#include "threadpool.h"//任务结构体
typedef struct Task
{void (*function) (void* arg);void* arg;
}Task;//线程池结构体
struct ThreadPool
{//任务队列Task* taskQ;int queueCapacity;     //容量int queueSize;         //当前任务个数int queueFront;        //队头->取数据int queueRear;         //队尾->放数据pthread_t managerID;   //管理者线程IDpthread_t *threadIDs;  //工作的线程IDint minNum;            //最小线程数量int maxNum;            //最大线程数量int busyNum;           //忙的线程的个数int liveNum;           //存活的线程的个数int exitNum;           //要销毁的线程个数pthread _mutex_t mutexPool;       //锁整个的线程池pthread_mutex_t mutexBusy;        //锁busyNum变量            pthread_cond_t notFull;           //任务队列是不是满了pthread_cond_t notEmpty;          //任务队列是不是空了int shutdown;               //是不是要销毁线程池,销毁为1,不销毁为0
};

三、创建线程池实例

typedef struct ThreadPool ThreadPool;
ThreadPool* threadPoolCreate(int min, int max, int queueSize)
{ThreadPool* pool=(ThreadPool*)malloc(sizeof (ThreadPool));do{if (pool == NULL){printf ( "malloc threadpool fail ... \n");break;}pool->threadIDs = (pthread_t *) malloc(sizeof(pthread_t) *max);if(pool->threadIDs == NULL){printf ("malloc threadIDs fail ... \n");break;}memset(pool->threadIDs,0, sizeof (pthread_t) * max);pool->minNum = min;pool->maxNum = max;pool->busyNum = 0;pool->liveNum = min; //和最小个数相等pool->exitNum = 0;if (pt.hread _mutex_init ( &pool->mutexPool,NUTI) !=0 ||pthread_mutex_init ( &pool->mutexBusy,NULL) !=0 ||pthread_cond_init (&pool->notEmpty,NULL) !=0 ||pthread_cond_init ( &pool->notFull,NULL) !=0 ){    printf ( "mutex or condition init fail ...\n");break;}//任务队列pool->taskQ = malloc(sizeof (Task) * queueSize);pool->queueCapacity =qucuesizo;pool->queueSize= 0;pool->queueFront =0;pool->queueRear = 0;pool->shutdown = 0;//创建线程pthread_create ( &pool->managerID,NULL,manager,NULL);for (int i = 0; i < min; ++i){pthread create (&pool->threadIDs[i],NULL,worker,NULL);}}whiie (O);//释放资源if(pool && pool->threadIDs) free(pool->threadIDs);if(pool && pool->taskQ) free(pool->taskQ);if(pool) free(pool);return NULL;
}

四、添加工作的线程的任务函数

void* worker (void* arg)
{ThreadPool* pool = (ThreadPool*)arg;while (1){pthread_ mutex_lock(&pool->mtexPool) ;!当前任务队列是否为空while (pool->queuesize == 0 && !pool->shutdown ){//阻塞工作线程pthread_cond_wait(&pool->notEmpty, &pool->mutexPool);//判断是不是要销毁线程if (pool->exitNum > 0){pool->exitNum--;pthread_ mutex_unlock(&pool->mtexPool) ;!当前任务队列是否为空pthread_exit (NULL);}}//判断线程池是否被关闭了if (pool->shutdown ){pthread_mutex_unlock(&pool->mutexPool);pthread_exit(NULL);}//从任务队列中取出一个任务Task task;task.function = pool->taskQ[pool->queueFront].function;task.arg = pool->taskQ[pool->queueFront].arg;//移动头结点pool->queueFront =(pool->queueFront + 1) % pool->queueCapacity;pool->queuesize--;//解锁pthread_cond_signal(&pool->notFull);pthread_mutex_unlock(&pool->mutexPool);printf("thread %ld start working ...\n");pthread mutex_lock (&pool->mutexBusy);pool->busyNum++;pthread mutex_unlock (&pool->mutexBusy) ;task.function(task.arg) ; //或者 (*task.function) (task.arg) 进行调用;free(task.arg);task.arg=NULL;printf("thread %ld end working ...\n");pthread_mutex_lock (&pool->mutexBusy);pool->busyNum--;pthread mutex_unlock (&pool->mutexBusy) ;     }return NULL;
}

五、管理者线程的任务函数

const int NUMBER = 2;
void* manaqer(void* arg)
{ThreadPool* pool = (ThreadPool+)arg;while(!pool->shutdown){//每隔3s检测一次sleep(3);//取出线程池中任务的数量和当前线程的数量pthread_mutex_lock(&pool->muatexPool) ;int queueSize =pool->queuesize;int liveNum = pool->liveNum;pthread_mutex_unlock( &pool->mutexPool) ;//取出忙的线程的数量pthread_mutex_lock(&pool->mutexBusy);int busyNum = pool->busyNum;pthread_mutex__lock(&pool->mutexBusy) ;//添加线程// 任务的个数 > 存活的线程个数 && 存活的线程数 < 最大线程数if (queueSize > liveNum && liveNum< pool->maxNum){pthread_mutex_lock(&pool->mutexPool);int counter = 0;for (int i = 0; i < pool->maxNum && counter < NUMBER && pool->liveNum < pool->maxNum ; ++i){if (pool->threadIDs[i] == 0){pthread_create( &pool->threadIDs[i],NULI,worker, pool);counter++;pool->liveNum++;}}pthread_mutex_unlock(&pool->mutexPool);}// 销毁线程// 忙的线程*2 < 存活的线程数 && 存活的线程 > 最小线程数if(busyNum * 2< liveNum && liveNum > pool->minNum){pthread_mutex_lock(&pool->mutexPool);pool->exitNum = NUMBER;pthread_mutex_unlock(&pcol->mutexPool);// 让工作的线程自杀Ifor(int i=0;i<NUMBER; ++i){pthread_cond_signal(&pool->notEmpty);}}}
}

六、往线程池中添加任务

void threadPoolAdd(ThreadPool* pool,void (*func)(void*), void* arg)
{pthread_mutex_lock(&pool->mutexPool);while(pool->queueSize == pool->queueCapacity && !pool->shutdown){//阻塞生产者线程pthread_cond_wait( &pool->notFull,&pool->mutexPool) ;}if (pool->shutdown){pthread_mutex_unlock ( &pool->mutexPool) ;return;}//添加任务pool->taskQ[pool->queueRear].function = func;pool->taskQ[pool->queueRear].arg = arg;pool->queueRear = (pool->queueRear + 1) % pool->queueCapacity;pool->queuesize++;pthread_cond_signal( &pool->notEmpty);pthread_mutex_unlock(&pool->mutexPool) ;
}

七、获取线程池工作的线程数量与活着的线程数量

//获取线程池中工作的线程数量
int threadPoolBusyNum ( ThreadPool* pool)
{pthread_mutex_lock(&pool->mutexBusy);int busyNum = pool->busyNum;pthread_mutex_unlock(&pool->mutexBusy);return busyNum;
}//获取线程池中活着的线程数量
int threadPoolAliveNum (ThreadPool*pool)
{pthread_mutex_lock(&pool->mutexPool);int busyNum = pool->liveNum;pthread_mutex_unlock(&pool->mutexPool);return aliveNum;
}

八、线程池的销毁

int threadPoolDestroy (ThreadPool* pool)
{if(pool == NULL){return -1;}//关闭线程池pool->shutdown = 1;//阻塞回收管理者线程pthread_join(pool->nanagerID,NULL);//唤醒阻塞的消费者线程for (int i = 0; i < pool->liveNum; ++i){pthread_cond_signal( &pool->notEmpty) ;}//释放堆内存if(pool->taskQ){free(pool->taskQ);pool->taskQ=NULL;}if(pool->threadIDs){free(pool->threadIDs);pool->threadIDs=NULL;}free(pool);pool=NULL;pthread_mutex_destroy( &pool->mutexPool);pthread_mutex_destroy( &pool->mutexBusy);pthread_cond_ destroy( &pool->notEmpty);pthread_cond_destroy ( &pool->notFull);return 0;
}


 

http://www.tj-hxxt.cn/news/6084.html

相关文章:

  • 网站建设费应计入什么科目苏州整站优化
  • 加快门户网站建设企业内训课程
  • 网络科技公司企业文化搜索关键词优化服务
  • 设计常用网站个人信息怎么在百度推广
  • 南宁网站建设外包全网营销图片
  • 商机互联公司做网站怎么样什么是seo关键词
  • 高端网站定制策划个人主页网页设计
  • 科技网站建设清远疫情防控措施
  • 做网站行业怎么样今日nba数据帝
  • 网站语言有几种搜资源
  • 建手机网站款软件seo快速排名优化方式
  • wordpress主题08影视seo是什么岗位
  • 久久建筑网会员每日登录怎么优化关键词
  • 网站建设服务哪家好站长工具传媒
  • 做网站只用php不用html营销策划公司主要做些什么
  • 如何做盗版小说网站湖南seo排名
  • asp网站怎么做百度指数平台官网
  • 网络工程师和做网站哪个难搜索引擎优化是什么?
  • 天津百度做网站多少钱google play谷歌商店
  • 东城区住房和建设委员会网站他达那非片能延时多久
  • 本地网站可以做吗怎么在百度上做网站
  • 网站建设百强企业软文代写多少钱一篇
  • wordpress网站怎么加速百度竞价排名一年费用
  • dedecms网站地图哪有学电脑培训班
  • 怎么找做网站的开发一个网站的步骤流程
  • 移动端网站开发流程图手机百度高级搜索
  • 做网站和做微信小程序百度推广咨询
  • 网站建设服务费怎么入账网络安全培训机构哪家好
  • 重庆建网站方法关键词排名点击软件
  • 手机制作最简单钓鱼网站网站推广优化外包便宜