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

摄影网站制作步骤html祥云网站优化

摄影网站制作步骤html,祥云网站优化,wordpress评论获取qq,网页设计需要学什么东西目录 线程池的实现过程 线程池的创建 添加任务队列 线程进行处理任务 线程池资源释放 线程池完整程序 线程池v1.0版本总结 线程池的实现过程 实现线程池首先要确定线程池有哪些属性 线程池中线程的数量线程池中已工作的线程数量任务队列任务队列的大小任务队列的锁 还…目录 线程池的实现过程 线程池的创建 添加任务队列 线程进行处理任务 线程池资源释放 线程池完整程序 线程池v1.0版本总结 线程池的实现过程 实现线程池首先要确定线程池有哪些属性 线程池中线程的数量线程池中已工作的线程数量任务队列任务队列的大小任务队列的锁 还需要确定线程池的三种条件情况 1任务队列为空时线程池里的线程需要阻塞等待 2任务队列为满不能再新增任务 3任务队列不为空线程池里的线程处理任务 线程池的创建 定义任务队列结构体 所有任务以函数指针的方式存储。 struct job {void *(*func)(void *arg);void *arg;struct job *next; }; 定义线程池结构体 struct threadpool {int thread_num; //已开启的线程数量pthread_t *pthread_ids; //保存线程池中线程的idstruct job *head; //任务队列的头struct job *tail; //任务队列的尾int queue_max_num; //任务队列的最大数int queue_cur_num; //任务队列已有多少个任务pthread_mutex_t mutex;pthread_cond_t queue_empty; //控制任务队列为空的条件pthread_cond_t queue_not_empty; //控制任务队列不为空的条件pthread_cond_t queue_not_full; //控制任务队列不为满的条件 }; 在main函数中创建一个线程池并初始化线程池中线程数量和任务数量最后分配线程号 struct threadpool *pool (struct threadpool*)malloc(sizeof(struct threadpool));//mallocint thread_num 20;int queue_max_num 100;pool-thread_num thread_num;pool-pthread_ids malloc(sizeof(pthread_t)*thread_num);//malloc 接着创建线程池中线程注意要将线程池作为参数传入到线程处理函数中让每个线程知道当前属于哪个线程池还要知道当前处理的是哪个任务队列任务队列的头和尾刚好存储在线程池中。 注也可以将struct threadpool *pool (struct threadpool*)malloc(sizeof(struct threadpool));放在全局范围内这样每个线程都可以看到但是不安全。因此我们定义为局部变量。 void* threadpool_function(void *arg){struct threadpool *pool (struct threadpool*)arg;while (1){}}...int main()...for(int i 0;ipool-thread_num;i){pthread_create((pool-pthread_ids[i]),NULL,threadpool_function,(void*)pool);}... 初始化任务队列 pool-queue_max_num queue_max_num;pool-queue_cur_num0;pool-headNULL;pool-tailNULL; 最后初始化锁和条件变量 pthread_mutex_init((pool-mutex),NULL);pthread_cond_init((pool-queue_empty),NULL);pthread_cond_init((pool-queue_not_empty),NULL);pthread_cond_init((pool-queue_not_full),NULL); 对于上面线程池的创建我们可以封装成一个函数 struct threadpool* threadpool_init(int thread_num,int queue_max_num) {struct threadpool *pool (struct threadpool*)malloc(sizeof(struct threadpool));//mallocpool-queue_max_num queue_max_num;pool-queue_cur_num0;pool-headNULL;pool-tailNULL;pthread_mutex_init((pool-mutex),NULL);pthread_cond_init((pool-queue_empty),NULL);pthread_cond_init((pool-queue_not_empty),NULL);pthread_cond_init((pool-queue_not_full),NULL);pool-thread_num thread_num;pool-pthread_ids malloc(sizeof(pthread_t)*thread_num);//mallocfor(int i 0;ipool-thread_num;i){pthread_create((pool-pthread_ids[i]),NULL,threadpool_function,(void*)pool);}return pool; } 我们一个要实现三个接口创建好线程池之后线程池需要去处理任务我们还需要向任务队列里面添加任务。 线程池怎么用核心就是实现线程池里面的线程处理函数再一个就是往任务队列里添加任务。 添加任务队列 线程如何工作需要依托于任务队列里的任务来做因此我们先不继续写线程处理函数我们先往任务队列里存放任务。 任务队列里每一个节点放的是一个函数指针我们将想要每个线程做的操作封装成一个函数然后把函数的地址传给这个指针。这样的话每一个节点函数指针对应的就是所要执行的任务。 我们让每个任务都打印两句话 void *work(void *arg) {char *p (char *)arg;printf(hello world! %s\n, p);printf(welcome to Nanjing! %s\n, p);sleep(1); } 我们将向任务队列里添加一个任务的操作也封装成函数 void threadpool_add_job(struct threadpool *pool, void *(*func)(void *arg), void *arg) {struct job *pjob (struct job *)malloc(sizeof(struct job));pjob-func func;pjob-arg arg;if (pool-head NULL){pool-head pool-tail pjob;}else{pool-tail-next pjob;pool-tail pjob;}pool-queue_cur_num; } 上面只是最基本的添加任务我们还需要对任务队列进行状态判断 对任务队列已满的情况添加进来将上锁解锁和条件变量用上 void threadpool_add_job(struct threadpool *pool, void *(*func)(void *arg), void *arg) {pthread_mutex_lock((pool-mutex));//如果任务队列已满while(pool-queue_cur_num pool-queue_max_num){pthread_cond_wait((pool-queue_not_full),(pool-mutex));}struct job *pjob (struct job *)malloc(sizeof(struct job));pjob-func func;pjob-arg arg;if (pool-head NULL){pool-head pool-tail pjob;}else{pool-tail-next pjob;pool-tail pjob;}pool-queue_cur_num;pthread_mutex_unlock((pool-mutex)); } 线程进行处理任务 在线程处理函数中对任务队列进行任务处理线程的工作方式是每次从任务队列取一个任务去执行操作执行完成之后回头来再取来回往复 void *threadpool_function(void *arg) {struct threadpool *pool (struct threadpool *)arg;struct job *pjob NULL;while (1){pthread_mutex_lock((pool-mutex));pjob pool-head;pool-queue_cur_num--;if(pool-queue_cur_num0){pool-head pool-tailNULL;}else{pool-headpool-head-next;}pthread_mutex_unlock((pool-mutex));(*(pjob-func))(pjob-arg);free(pjob);pjobNULL;} } 但是我们在向任务队列添加任务前就已经创建好了线程池也就是说线程会在任务添加进前已经运行。因此对于线程处理函数中pjob pool-head;第7行如果开始时任务还没来得及添加进任务队列会导致pool-head为NULL从而导致 pool-headpool-head-next; 以及 (*(pjob-func))(pjob-arg);发生段错误。 因此还需要进行判断任务队列是否为空使用条件变量进行阻塞等待任务添加进来 void *threadpool_function(void *arg) {struct threadpool *pool (struct threadpool *)arg;struct job *pjob NULL;while (1){pthread_mutex_lock((pool-mutex));//判断任务队列是否为空while(pool-queue_cur_num 0){pthread_cond_wait((pool-queue_not_empty),(pool-mutex));}pjob pool-head;pool-queue_cur_num--;if(pool-queue_cur_num0){pool-head pool-tailNULL;}else{pool-headpool-head-next;}pthread_mutex_unlock((pool-mutex));(*(pjob-func))(pjob-arg);free(pjob);pjobNULL;} } 然后在添加任务队列函数中如果任务队列为空就进行广播解阻塞 void threadpool_add_job(struct threadpool *pool, void *(*func)(void *arg), void *arg){...if (pool-head NULL){pool-head pool-tail pjob;pthread_cond_broadcast((pool-queue_not_empty));}...} 在main函数中创建10个任务 int main(int argc, char const *argv[]) {struct threadpool *pool threadpool_init(10, 100);threadpool_add_job(pool,work,1);threadpool_add_job(pool,work,2);threadpool_add_job(pool,work,3);threadpool_add_job(pool,work,4);threadpool_add_job(pool,work,5);threadpool_add_job(pool,work,6);threadpool_add_job(pool,work,7);threadpool_add_job(pool,work,8);threadpool_add_job(pool,work,9);threadpool_add_job(pool,work,10);while(1);return 0; } 运行效果如下 所有的任务都被执行了执行顺序由线程调度器的时间片调度决定 对于任务队列已满的条件变量我们还需要在线程处理函数中判断进行解阻塞 void threadpool_add_job(struct threadpool *pool, void *(*func)(void *arg), void *arg) { ... ... //如果任务队列已满 while(pool-queue_cur_num pool-queue_max_num) {pthread_cond_wait((pool-queue_not_full),(pool-mutex)); } ... } 线程处理函数 void *threadpool_function(void *arg) {struct threadpool *pool (struct threadpool *)arg;struct job *pjob NULL;while (1){pthread_mutex_lock((pool-mutex));while(pool-queue_cur_num 0){pthread_cond_wait((pool-queue_not_empty),(pool-mutex));}pjob pool-head;pool-queue_cur_num--;//对任务队列满队条件变量解阻塞if(pool-queue_cur_num!pool-queue_max_num){pthread_cond_broadcast((pool-queue_not_full));}if(pool-queue_cur_num0){pool-head pool-tailNULL;}else{pool-headpool-head-next;}pthread_mutex_unlock((pool-mutex));(*(pjob-func))(pjob-arg);free(pjob);pjobNULL;} } 至此线程池的全部实现已完成80%我们还需要对线程池进行线程资源释放等操作如果不销毁会导致僵尸线程。 线程池资源释放 我们一定要当任务队列为空的时候才能对线程池进行销毁因此我们在线程销毁函数里要使用任务为空的条件变量进行阻塞等待 void thread_destroy(struct threadpool *pool) {pthread_mutex_lock((pool-mutex));while(pool-queue_cur_num !0){pthread_cond_wait((pool-queue_empty),(pool-mutex));}pthread_mutex_unlock((pool-mutex)); ... ... } 在线程函数中当判断任务数量为0时进行信号量解阻塞 ... if(pool-queue_cur_num0) {pool-head pool-tailNULL;pthread_cond_broadcast((pool-queue_empty)); } ... 而当任务队列里任务为空时所有线程都将阻塞 因此我们在要销毁线程的时候通知所有阻塞的线程继续执行可省略线程池资源回收函数如下其中要注意使用pthread_cancel进行线程退出时线程需要有系统调用如sleep void thread_destroy(struct threadpool *pool) {pthread_mutex_lock((pool-mutex));while(pool-queue_cur_num !0){pthread_cond_wait((pool-queue_empty),(pool-mutex));}pthread_mutex_unlock((pool-mutex));//通知所有阻塞的线程pthread_cond_broadcast((pool-queue_not_empty));pthread_cond_broadcast((pool-queue_not_full));//可不要for(int i0;ipool-thread_num;i){printf(thread exit!\n);pthread_cancel(pool-pthread_ids[i]);pthread_join(pool-pthread_ids[i],NULL);}pthread_mutex_destroy((pool-mutex));pthread_cond_destroy((pool-queue_empty));pthread_cond_destroy((pool-queue_not_empty));pthread_cond_destroy((pool-queue_not_full));free(pool-pthread_ids);//为了以防万一任务队列不为空要对所有任务进行销毁struct job *temp;while(pool-head!NULL){temp pool-head;pool-headtemp-next;free(temp);}free(pool); } 线程池完整程序 #include stdio.h #include stdlib.h #include string.h #include pthread.h #include unistd.h struct job {void *(*func)(void *arg);void *arg;struct job *next; };struct threadpool {int thread_num; //已开启的线程数量pthread_t *pthread_ids; //保存线程池中线程的idstruct job *head; //任务队列的头struct job *tail; //任务队列的尾int queue_max_num; //任务队列的最大数int queue_cur_num; //任务队列已有多少个任务pthread_mutex_t mutex;pthread_cond_t queue_empty; //控制任务队列为空的条件pthread_cond_t queue_not_empty; //控制任务队列不为空的条件pthread_cond_t queue_not_full; //控制任务队列不为满的条件 };void *threadpool_function(void *arg) {struct threadpool *pool (struct threadpool *)arg;struct job *pjob NULL;while (1){pthread_mutex_lock((pool-mutex));while(pool-queue_cur_num 0){pthread_cond_wait((pool-queue_not_empty),(pool-mutex));}pjob pool-head;pool-queue_cur_num--;//对任务队列满队条件变量解阻塞if(pool-queue_cur_num!pool-queue_max_num){pthread_cond_broadcast((pool-queue_not_full));}if(pool-queue_cur_num0){pool-head pool-tailNULL;pthread_cond_broadcast((pool-queue_empty));}else{pool-headpool-head-next;}pthread_mutex_unlock((pool-mutex));(*(pjob-func))(pjob-arg);free(pjob);pjobNULL;} }struct threadpool *threadpool_init(int thread_num, int queue_max_num) {struct threadpool *pool (struct threadpool *)malloc(sizeof(struct threadpool));// mallocpool-queue_max_num queue_max_num;pool-queue_cur_num 0;pool-head NULL;pool-tail NULL;pthread_mutex_init((pool-mutex), NULL);pthread_cond_init((pool-queue_empty), NULL);pthread_cond_init((pool-queue_not_empty), NULL);pthread_cond_init((pool-queue_not_full), NULL);pool-thread_num thread_num;pool-pthread_ids malloc(sizeof(pthread_t) * thread_num);// mallocfor (int i 0; i pool-thread_num; i){pthread_create((pool-pthread_ids[i]), NULL, threadpool_function, (void *)pool);}return pool; }void threadpool_add_job(struct threadpool *pool, void *(*func)(void *arg), void *arg) {pthread_mutex_lock((pool-mutex));//如果任务队列已满while(pool-queue_cur_num pool-queue_max_num){pthread_cond_wait((pool-queue_not_full),(pool-mutex));}struct job *pjob (struct job *)malloc(sizeof(struct job));pjob-func func;pjob-arg arg;if (pool-head NULL){pool-head pool-tail pjob;pthread_cond_broadcast((pool-queue_not_empty));}else{pool-tail-next pjob;pool-tail pjob;}pool-queue_cur_num;pthread_mutex_unlock((pool-mutex)); }void thread_destroy(struct threadpool *pool) {pthread_mutex_lock((pool-mutex));while(pool-queue_cur_num !0){pthread_cond_wait((pool-queue_empty),(pool-mutex));}pthread_mutex_unlock((pool-mutex));//通知所有阻塞的线程pthread_cond_broadcast((pool-queue_not_empty));pthread_cond_broadcast((pool-queue_not_full));//可不要for(int i0;ipool-thread_num;i){printf(thread exit!\n);pthread_cancel(pool-pthread_ids[i]);pthread_join(pool-pthread_ids[i],NULL);}pthread_mutex_destroy((pool-mutex));pthread_cond_destroy((pool-queue_empty));pthread_cond_destroy((pool-queue_not_empty));pthread_cond_destroy((pool-queue_not_full));free(pool-pthread_ids);//为了以防万一任务队列不为空要对所有任务进行销毁struct job *temp;while(pool-head!NULL){temp pool-head;pool-headtemp-next;free(temp);}free(pool); }void *work(void *arg) {char *p (char *)arg;printf(hello world! %s\n, p);printf(welcome to Nanjing! %s\n, p);sleep(1); }int main(int argc, char const *argv[]) {struct threadpool *pool threadpool_init(10, 100);threadpool_add_job(pool,work,1);threadpool_add_job(pool,work,2);threadpool_add_job(pool,work,3);threadpool_add_job(pool,work,4);threadpool_add_job(pool,work,5);threadpool_add_job(pool,work,6);threadpool_add_job(pool,work,7);threadpool_add_job(pool,work,8);threadpool_add_job(pool,work,9);threadpool_add_job(pool,work,10);threadpool_add_job(pool,work,11);threadpool_add_job(pool,work,12);threadpool_add_job(pool,work,13);threadpool_add_job(pool,work,14);threadpool_add_job(pool,work,15);threadpool_add_job(pool,work,16);threadpool_add_job(pool,work,17);threadpool_add_job(pool,work,18);threadpool_add_job(pool,work,19);threadpool_add_job(pool,work,20);thread_destroy(pool);sleep(5);return 0; }线程池v1.0版本总结 我们现在实现的线程池比如线程数量定义为10如果任务数量很多的情况下就会导致线程池运行效率下降。而如果定义的线程数量很多而任务数量很少就会导致资源浪费。 概况来说就是以下两个问题 线程数量小但任务多导致效率下降线程数量多但任务少导致资源浪费 我们可以根据任务的多少来动态分配线程池中线程的个数当任务队列里任务很多但线程数量很少的时候我们就往线程池里增加线程而当任务队列里任务数量少但线程数量多的情况我们就关闭一些线程。 线程池的v1.0版本到此全部介绍结束后面就来实现可伸缩性线程池。
http://wiki.neutronadmin.com/news/186278/

相关文章:

  • 网站建设致谢企业网站制作模板免费
  • 静态企业网站下载安卓应用软件开发
  • 龙岩e网站网络服务顺序
  • 自建网站营销网站 栏目
  • 开发大型网站的最主流语言wordpress主题更换
  • 辽宁大连建设工程信息网单页网站 seo
  • 网站价格评估 优帮云做企业网站注意些啥
  • 大同招聘网站建设山东建筑信息平台
  • 房地产集团网站欣赏服装设计公司图片
  • 营销型网站建设有哪些平台百度收录批量查询
  • 化妆品网站html模板羽毛球赛事安排
  • 南京建设项目环评公示期网站扁平手机网站
  • 医院网站 整站源码西安装修行业网站建设
  • 网站怎么做才能赚钱dz如何做门户网站
  • 百度云如何建设网站微信开发文档官网
  • 湛江市品牌网站建设怎么样互联网营销怎么赚钱
  • 南京做网站找哪家好安阳做网站哪家好
  • wordpress留言发送邮件给网站做排名优化学什么好处
  • 国外优秀app设计网站番禺建设网站服务
  • 做平面的网站cms 网站建设
  • 网站开发行情建设通网站上线
  • wordpress 音乐网百度seo优化教程免费
  • 企业首次建设网站方案流程招聘网站建设流程图
  • server 2008 r2搭建网站教育培训网站排名
  • 学校网站如何做做网站用什么系统
  • 做视频网站要多大的主机手机h5页面制作软件
  • 上海网站编辑招聘海南省城乡住房建设厅网站
  • php做一个网站福永网站建设公司哪家好
  • 网站内部seowordpress 忘记用户名
  • 网站建设调查表长臂挖机出租东莞网站建设