• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > C语言实现支持动态拓展和销毁的线程池

C语言实现支持动态拓展和销毁的线程池

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了c语言线程池,c语言实现线程池,c语言线程,c语言多线程编,c语言创建线程等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

本文实例介绍了C 语言实现线程池,支持动态拓展和销毁,分享给大家供大家参考,具体内容如下

实现功能

  • 1.初始化指定个数的线程
  • 2.使用链表来管理任务队列
  • 3.支持拓展动态线程
  • 4.如果闲置线程过多,动态销毁部分线程
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <signal.h>
 

/*线程的任务队列由,函数和参数组成,任务由链表来进行管理*/
typedef struct thread_worker_s{
  void *(*process)(void *arg); //处理函数
  void *arg;          //参数
  struct thread_worker_s *next;
}thread_worker_t;
 
#define bool int
#define true 1
#define false 0
 
/*线程池中各线程状态描述*/
#define THREAD_STATE_RUN        0
#define THREAD_STATE_TASK_WAITING   1
#define THREAD_STATE_TASK_PROCESSING  2
#define THREAD_STATE_TASK_FINISHED   3
#define THREAD_STATE_EXIT       4   
 
 
typedef struct thread_info_s{
  pthread_t id;
  int    state; 
  struct thread_info_s *next;
}thread_info_t;
 
static char* thread_state_map[] ={"创建","等待任务","处理中","处理完成","已退出"};
/*线程压缩的时候只有 0,1,2,4 状态的线程可以销毁*/
 
 
/*线程池管理器*/
#define THREAD_BUSY_PERCENT 0.5  /*线程:任务 = 1:2 值越小,说明任务多,增加线程*/
#define THREAD_IDLE_PERCENT 2   /*线程:任务 = 2:1 值大于1,线程多于任务,销毁部分线程*/
 
typedef struct thread_pool_s{
  pthread_mutex_t queue_lock ; //队列互斥锁,即涉及到队列修改时需要加锁
  pthread_cond_t queue_ready; //队列条件锁,队列满足某个条件,触发等待这个条件的线程继续执行,比如说队列满了,队列空了
 
  thread_worker_t *head   ;    //任务队列头指针
  bool    is_destroy   ;    //线程池是否已经销毁
  int num;              //线程的个数
  int rnum;         ;    //正在跑的线程
  int knum;         ;    //已杀死的线程
  int queue_size       ;    //工作队列的大小 
  thread_info_t *threads   ;    //线程组id,通过pthread_join(thread_ids[0],NULL) 来执行线程
  pthread_t   display   ;    //打印线程
  pthread_t   destroy   ;    //定期销毁线程的线程id
  pthread_t   extend    ;
  float percent       ;    //线程个数于任务的比例 rnum/queue_size
  int  init_num      ;
  pthread_cond_t  extend_ready     ;    //如果要增加线程
}thread_pool_t;
 
/*-------------------------函数声明----------------------*/
/**
 * 1.初始化互斥变量
 * 2.初始化等待变量
 * 3.创建指定个数的线程线程
 */
thread_pool_t* thread_pool_create(int num);
void *thread_excute_route(void *arg);
 
 
/*调试函数*/
void debug(char *message,int flag){
  if(flag)
    printf("%s\n",message);
}
 
void *display_thread(void *arg);
/**
 * 添加任务包括以下几个操作
 * 1.将任务添加到队列末尾
 * 2.通知等待进程来处理这个任务 pthread_cond_singal();
*/
int thread_pool_add_worker(thread_pool_t *pool,void*(*process)(void *arg),void *arg); //网线程池的队列中增加一个需要执行的函数,也就是任务
 
/**
 * 销毁线程池,包括以下几个部分
 * 1.通知所有等待的进程 pthread_cond_broadcase
 * 2.等待所有的线程执行完
 * 3.销毁任务列表
 * 4.释放锁,释放条件
 * 4.销毁线程池对象
 */
 
 
 
void *thread_pool_is_need_recovery(void *arg);
void *thread_pool_is_need_extend(void *arg);
void thread_pool_destory(thread_pool_t *pool);
 
 
thread_pool_t *thread_pool_create(int num){
  if(num<1){
    return NULL;
  }
  thread_pool_t *p;
  p = (thread_pool_t*)malloc(sizeof(struct thread_pool_s));
  if(p==NULL)
    return NULL;
  p->init_num = num;
  /*初始化互斥变量与条件变量*/
  pthread_mutex_init(&(p->queue_lock),NULL);
  pthread_cond_init(&(p->queue_ready),NULL);
 
  /*设置线程个数*/
  p->num  = num; 
  p->rnum = num;
  p->knum = 0;
 
  p->head = NULL;
  p->queue_size =0; 
  p->is_destroy = false;
 
   
  int i=0;
  thread_info_t *tmp=NULL;
  for(i=0;i<num;i++){
    /*创建线程*/
    tmp= (struct thread_info_s*)malloc(sizeof(struct thread_info_s));
    if(tmp==NULL){
      free(p);
      return NULL;
    }else{
      tmp->next = p->threads;
      p->threads = tmp;
    }
    pthread_create(&(tmp->id),NULL,thread_excute_route,p);
    tmp->state = THREAD_STATE_RUN;
  }
 
  /*显示*/
  pthread_create(&(p->display),NULL,display_thread,p);
  /*检测是否需要动态线程*/
  //pthread_create(&(p->extend),NULL,thread_pool_is_need_extend,p);
  /*动态销毁*/
  pthread_create(&(p->destroy),NULL,thread_pool_is_need_recovery,p);
  return p;
}
 
int thread_pool_add_worker(thread_pool_t *pool,void*(*process)(void*arg),void*arg){
  thread_pool_t *p= pool;
  thread_worker_t *worker=NULL,*member=NULL;
  worker = (thread_worker_t*)malloc(sizeof(struct thread_worker_s));
  int incr=0;
  if(worker==NULL){
    return -1;
  }
  worker->process = process;
  worker->arg   = arg;
  worker->next  = NULL;
  thread_pool_is_need_extend(pool);
  pthread_mutex_lock(&(p->queue_lock));
  member = p->head;
  if(member!=NULL){
    while(member->next!=NULL)
      member = member->next;
    member->next = worker;
  }else{
    p->head = worker;
  }
  p->queue_size ++;
  pthread_mutex_unlock(&(p->queue_lock));
  pthread_cond_signal(&(p->queue_ready));
  return 1;
}
 
 
void thread_pool_wait(thread_pool_t *pool){
  thread_info_t *thread;
  int i=0;
  for(i=0;i<pool->num;i++){
    thread = (thread_info_t*)(pool->threads+i);
    thread->state = THREAD_STATE_EXIT;
    pthread_join(thread->id,NULL);
  }
}
void thread_pool_destory(thread_pool_t *pool){
  thread_pool_t  *p   = pool;
  thread_worker_t *member = NULL;
 
  if(p->is_destroy)
    return ;
  p->is_destroy = true;
  pthread_cond_broadcast(&(p->queue_ready));
  thread_pool_wait(pool);
  free(p->threads);
  p->threads = NULL;
  /*销毁任务列表*/
  while(p->head){
    member = p->head;
    p->head = member->next;
    free(member);
  }
  /*销毁线程列表*/
  thread_info_t *tmp=NULL;
  while(p->threads){
    tmp = p->threads;
    p->threads = tmp->next;
    free(tmp);
  }
 
  pthread_mutex_destroy(&(p->queue_lock));
  pthread_cond_destroy(&(p->queue_ready));
  return ;
}
/*通过线程id,找到对应的线程*/
thread_info_t *get_thread_by_id(thread_pool_t *pool,pthread_t id){
  thread_info_t *thread=NULL;
  thread_info_t *p=pool->threads;
  while(p!=NULL){
    if(p->id==id)
      return p;
    p = p->next;
  }
  return NULL;
}
 
 
/*每个线程入口函数*/
void *thread_excute_route(void *arg){
  thread_worker_t *worker = NULL;
  thread_info_t  *thread = NULL; 
  thread_pool_t*  p = (thread_pool_t*)arg;
  //printf("thread %lld create success\n",pthread_self());
  while(1){
    pthread_mutex_lock(&(p->queue_lock));
 
    /*获取当前线程的id*/
    pthread_t pthread_id = pthread_self();
    /*设置当前状态*/
    thread = get_thread_by_id(p,pthread_id);
 
    /*线程池被销毁,并且没有任务了*/
    if(p->is_destroy==true && p->queue_size ==0){
      pthread_mutex_unlock(&(p->queue_lock));
      thread->state = THREAD_STATE_EXIT;
      p->knum ++;
      p->rnum --;
      pthread_exit(NULL);
    }
    if(thread){
      thread->state = THREAD_STATE_TASK_WAITING; /*线程正在等待任务*/
    }
    /*线程池没有被销毁,没有任务到来就一直等待*/
    while(p->queue_size==0 && !p->is_destroy){
      pthread_cond_wait(&(p->queue_ready),&(p->queue_lock));
    }
    p->queue_size--;
    worker = p->head;
    p->head = worker->next;
    pthread_mutex_unlock(&(p->queue_lock));
     
 
    if(thread)
      thread->state = THREAD_STATE_TASK_PROCESSING; /*线程正在执行任务*/
    (*(worker->process))(worker->arg);
    if(thread)
      thread->state = THREAD_STATE_TASK



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C语言实现支持动态拓展和销毁的线程池

相关文章

  • 2017-05-28VC++实现选择排序算法简单示例
  • 2017-05-28C++ 类访问控制的条件总结
  • 2017-05-28C++学生信息管理系统
  • 2017-05-28平衡二叉树的实现实例
  • 2017-05-28C++入门之基础语法学习教程
  • 2017-05-28c语言中位字段与结构联合的组合使用详解
  • 2017-05-28深入解析最长公共子串
  • 2017-05-28C++非递归建立二叉树实例
  • 2017-05-28C语言程序设计50例(经典收藏)
  • 2017-05-28C语言 数据结构之中序二叉树实例详解

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 简单说说STL的内存管理
    • c++ builder TreeView控件节点遍历代码
    • c语言判断是否素数程序代码
    • C语言编程时常犯十八个错误小结
    • C语言职工管理系统设计
    • C语言中#define与typedef的互换细节详解
    • c++ 构造函数的初始化列表
    • HDOJ 1443 约瑟夫环的最新应用分析详解
    • VC++中图像处理类CBitmap的用法
    • 关于函数调用方式__stdcall和__cdecl详解

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有