linux下模拟线程池
来源:互联网 发布:js设置css样式 编辑:程序博客网 时间:2024/05/30 04:57
当需要利用线程大量处理任务时,使用线程池可以减小大量创建、销毁线程的开销,特别是任务处理时间短时更能节省系统资源。
线程池的基本原理是在任务执行开始前,就预先创建一定数量的线程放入线程列表(链表,数组,队列等)中,创建这些线程都是处于休眠状态。当任务到来后,从线程池中选择一个空闲的线程,用此线程执行,如果无空闲的线程则创建新的线程来处理,并将些线程加入线程池。任务执行完成之后,将线程重新阻塞,等待下一次任务。当一定量的线程处于阻塞状态时,自动销毁线程池中的部分的线程
thread_pool.h
#ifndef __THREAD_POOL__#define __THREAD_POOL__typedef void *(*handle_fun)(void *arg);typedef struct{ uint32_t min_th; /*保持的最少线程数*/ uint32_t cur_th; /*线程池中当前线程数*/ uint32_t max_th; /*允许的最大线程数*/ uint32_t free_th; pthread_mutex_t pool_lock; list_t *threads; /*list of threads*/ pthread_t monitor_th;}thread_pool;int has_cap_to_process_task_queue(thread_pool *pool);int task_process(thread_pool *pool, process_fun fun, void *arg);thread_pool *thread_pool_create(uint32_t min, uint32_t max);#endif
thread_pool.c
/****************************************************************************** zgang 2013/9/10******************************************************************************/#include <stdio.h>#include <unistd.h>#include <string.h>#include <pthread.h>#include <signal.h>#include <stdlib.h>#include "hm_types.h"#include "hm_util.h"#include "thread_pool.h"typedef struct{ pthread_t thread_id; uint8_t is_busy; uint8_t to_be_die; pthread_cond_t cond; pthread_mutex_t lock; handle_fun proc; void *arg; thread_pool *pool; listnode_t *node;}thread_info;#define LOCK_POOL(_pool) \ pthread_mutex_lock(&_pool->pool_lock)#define UNLOCK_POOL(_pool) \ pthread_mutex_unlock(&_pool->pool_lock)static void *work_thread(void *arg){ thread_info *info = (thread_info *)arg; thread_pool *pool = info->pool; listnode_t *node = info->node; list_t *list = pool->threads; while (1) { if (info->to_be_die) { break; } if (info->proc) { info->proc(info->arg); info->is_busy = FALSE; info->proc = NULL; LOCK_POOL(pool); node->data = info; node->prev = list->tail; node->next = NULL; if (list->head == NULL) list->head = node; else list->tail->next = node; list->tail = node; list->count++; UNLOCK_POOL(pool); } pthread_mutex_lock(&info->lock); pthread_cond_wait(&info->cond, &info->lock); pthread_mutex_unlock(&info->lock); } }/*从线程池中取出空闲线程*/static thread_info *get_idle_thread(thread_pool *pool){ thread_info *idle = NULL; listnode_t *node = NULL; list_t *idle_list = NULL; LOCK_POOL(pool); idle_list = pool->threads; if (idle_list->head == NULL || idle_list->count == 0) { UNLOCK_POOL(pool); return NULL; } node = idle_list->head; idle_list->head = node->next; if (!idle_list->head) idle_list->tail = NULL; else idle_list->head->prev = NULL; idle_list->count--; idle = node->data; idle->is_busy = TRUE; UNLOCK_POOL(pool); return idle;}/*向线程池添加新的线程*/static thread_info *add_new_thread_to_pool(thread_pool *pool){ thread_info *thread = NULL; LOCK_POOL(pool); if (pool->cur_th >= pool->max_th) { dpf("%d >= %d", pool->cur_th, pool->max_th); UNLOCK_POOL(pool); sleep(30); return NULL; } UNLOCK_POOL(pool); thread = (thread_info *)malloc(sizeof(thread_info)); if (thread == NULL) { dpf("memory error!"); sleep(30); return NULL; } memset(thread, 0, sizeof(thread_info)); pthread_cond_init(&thread->cond, NULL); pthread_mutex_init(&thread->lock, NULL); thread->proc = NULL; thread->arg = NULL; LOCK_POOL(pool); thread->pool = pool; thread->node = listnode_add(pool->threads, (void *)thread); UNLOCK_POOL(pool); if (pthread_create(&thread->thread_id, NULL, work_thread, thread) != 0) { LOCK_POOL(pool); listnode_delete(pool->threads, thread); UNLOCK_POOL(pool); dpf("create thread error!"); sleep(30); return NULL; } LOCK_POOL(pool); pool->cur_th++; UNLOCK_POOL(pool); usleep(10000); return thread;}int task_process(thread_pool *pool, handle_fun fun, void *arg){ thread_info *thread = NULL; thread = get_idle_thread(pool); if (thread) { thread->is_busy = TRUE; thread->proc = fun; thread->arg = arg; pthread_cond_signal(&thread->cond); /*唤醒线程*/ return 0; } else /*线程池中无空闲线程,则创建新的线程*/ { thread = add_new_thread_to_pool(pool); if (!thread) { thread->is_busy = TRUE; thread->proc = fun; thread->arg = arg; pthread_cond_signal(&thread->cond); return 0; } else { dpf("can't handle"); return 1; } }}int is_too_many_idle_threads(thread_pool *pool){ LOCK_POOL(pool); if (pool->cur_th <= pool->min_th) { UNLOCK_POOL(pool); return 0; } float free_thld = (float)(pool->threads->count) / pool->cur_th; UNLOCK_POOL(pool); if (free_thld > 0.5) // if half of threads are idle, kill some of them return 1; else return 0;}/*从线程池中删除进程*/void delete_thread_from_pool(thread_pool *pool){ thread_info *pthread = NULL; LOCK_POOL(pool); if (pool->cur_th <= pool->min_th) { UNLOCK_POOL(pool); return; } UNLOCK_POOL(pool); pthread = get_idle_thread(pool); if (pthread) { LOCK_POOL(pool); pool->cur_th--; UNLOCK_POOL(pool); pthread->to_be_die = TRUE; while (!pthread->to_be_die) { usleep(1000); pthread->to_be_die = TRUE; } pthread_cond_signal(&pthread->cond); usleep(10000); pthread_mutex_destroy(&pthread->lock); pthread_cond_destroy(&pthread->cond); free(pthread->node); free(pthread); }}/*监测线程数量*/static void *monitor_thread(void *arg){ thread_pool *pool = (thread_pool *)arg; while (1) { while (is_too_many_idle_threads(pool)) /*空闲线程过多,杀掉一部分*/ { delete_thread_from_pool(pool); } sleep(15); } return NULL;}int has_cap_to_process_task_queue(thread_pool *pool){ int rt = 0; LOCK_POOL(pool); rt = pool->threads->count; if (rt) { UNLOCK_POOL(pool); return 1; } else if (pool->cur_th < pool->max_th) { UNLOCK_POOL(pool); return 1; } else { UNLOCK_POOL(pool); return 0; }}static void free_thread_info(void *p){ free(p);}thread_pool *thread_pool_create(uint32_t min, uint32_t max){ int i = 0; thread_pool *pool = NULL; thread_info *thread = NULL; pool = (thread_pool *)malloc(sizeof(thread_pool)); if (pool == NULL) { return NULL; } memset(pool, 0, sizeof(pool)); pool->min_th = min; pool->max_th = max; pool->cur_th = min; pthread_mutex_init(&pool->pool_lock, NULL); pool->threads = list_new(); pool->threads->del = free_thread_info; for (i = 0; i < min; i++) { thread = (thread_info *)malloc(sizeof(thread_info)); if (thread == NULL) { list_delete(pool->threads); free(pool); return NULL; } memset(thread, 0, sizeof(thread_info)); pthread_cond_init(&thread->cond, NULL); pthread_mutex_init(&thread->lock, NULL); thread->proc = NULL; thread->arg = NULL; thread->pool = pool; thread->node = listnode_add(pool->threads, (void *)thread); if (pthread_create(&thread->thread_id, NULL, work_thread, thread) != 0) { list_delete(pool->threads); return NULL; } pthread_detach(thread->thread_id); usleep(50000); } if (pthread_create(&pool->monitor_th, NULL, monitor_thread, pool) != 0) { list_delete(pool->threads); return NULL; } usleep(1000); return pool;}
typedef struct listnode{ struct listnode *next; struct listnode *prev; void *data;}listnode_t;typedef void (*list_del_f)(void *val);typedef struct list{ listnode_t *head; listnode_t *tail; uint32_t count; list_del_f del;}list_t;void list_delete(list_t *list){ listnode_t *node = NULL; listnode_t *next = NULL; for (node = list->head; node; node = node->next) { if (list->del) { (*list->del)(node->data); } free(node); } free(list);}list_t *list_new(){ list_t *new = NULL; new = malloc(sizeof(list_t)); memset(new, 0, sizeof(list_t)); return new;}listnode_t *listnode_new(){ listnode_t *node = NULL; node = (listnode_t *)malloc(sizeof(listnode_t)); if (node == NULL) return NULL; memset(node, 0, sizeof(listnode_t)); return node;}listnode_t * listnode_add(list_t *list, void *val){ listnode_t *node = NULL; node = listnode_new(); if (node == NULL) return NULL; node->prev = list->tail; node->data = val; if (list->head == NULL) list->head = node; else list->tail->next = node; list->tail = node; list->count++; return node;}void listnode_delete(list_t *list, void *val){ listnode_t *node = NULL; for (node = list->head; node; node = node->next) { if (node->data == val) { if (node->prev) node->prev->next = node->next; else list->head = node->next; if (node->next) node->next->prev = node->prev; else list->tail = node->prev; list->count--; free(node); break; } }}
- linux下模拟线程池
- linux下线程池
- Linux下线程池
- linux 下线程池
- linux下线程池代码
- linux下线程池创建
- Linux下编写线程池
- Linux下线程池实现
- Linux下创建线程池
- Linux 下模拟键盘输入
- Linux 下模拟键盘输入
- Linux下模拟getch()
- java 模拟线程池
- 模拟线程池代码
- 模拟的线程池
- 线程池模拟实现
- Linux下通用线程池的构建
- Linux下的通用线程池创建
- lucene学习教程
- 如何制作 Python 安装模块(setup.py)
- Python 学习入门(3)—— 常用类库
- 第三讲.Classification and logistic regression (分类及logistic回归 / 二分类和多分类)
- 整理一些笔试题(要求手写代码的) 2011年以前的
- linux下模拟线程池
- 苏州大学月赛2013_month_10
- 基于Visual C++2013拆解世界五百强面试题--题12-进制转换
- dialog 的简单使用(简单的弹出一个对话框)
- java泛型 泛型的内部原理
- org.hibernate.HibernateException: createSQLQuery is not valid without active transaction
- Android Audio Subsystem - AudioTrack - play
- JAVA用jdbc连接SQLServer2005
- Hadoop学习之--Capaycity Scheduler配置参数说明