`
javathinker
  • 浏览: 241262 次
  • 来自: ...
文章分类
社区版块
存档分类
最新评论

C语言实现简单线程池

阅读更多

有时我们会需要大量线程来处理一些相互独立的任务,为了避免频繁的申请释放线程所带来的开销,我们可以使用线程池。下面是一个C语言实现的简单的线程池。

头文件:

   1: #ifndef THREAD_POOL_H__
   2: #define THREAD_POOL_H__
   3: 
   4: #include <pthread.h>
   5: 
   6: /* 要执行的任务链表 */
   7: typedef struct tpool_work {
   8:     void*               (*routine)(void*);       /* 任务函数 */
   9:     void                *arg;                    /* 传入任务函数的参数 */
  10:     struct tpool_work   *next;                    
  11: }tpool_work_t;
  12: 
  13: typedef struct tpool {
  14:     int             shutdown;                    /* 线程池是否销毁 */
  15:     int             max_thr_num;                /* 最大线程数 */
  16:     pthread_t       *thr_id;                    /* 线程ID数组 */
  17:     tpool_work_t    *queue_head;                /* 线程链表 */
  18:     pthread_mutex_t queue_lock;                    
  19:     pthread_cond_t  queue_ready;    
  20: }tpool_t;
  21: 
  22: /*
  23:  * @brief     创建线程池 
  24:  * @param     max_thr_num 最大线程数
  25:  * @return     0: 成功 其他: 失败  
  26:  */
  27: int
  28: tpool_create(int max_thr_num);
  29: 
  30: /*
  31:  * @brief     销毁线程池 
  32:  */
  33: void
  34: tpool_destroy();
  35: 
  36: /*
  37:  * @brief     向线程池中添加任务
  38:  * @param    routine 任务函数指针
  39:  * @param     arg 任务函数参数
  40:  * @return     0: 成功 其他:失败 
  41:  */
  42: int
  43: tpool_add_work(void*(*routine)(void*), void *arg);
  44: 
  45: #endif

实现:

   1: #include <unistd.h>
   2: #include <stdlib.h>
   3: #include <errno.h>
   4: #include <string.h>
   5: #include <stdio.h>
   6: 
   7: #include "tpool.h"
   8: 
   9: static tpool_t *tpool = NULL;
  10: 
  11: /* 工作者线程函数, 从任务链表中取出任务并执行 */
  12: static void* 
  13: thread_routine(void *arg)
  14: {
  15:     tpool_work_t *work;
  16:     
  17:     while(1) {
  18:         /* 如果线程池没有被销毁且没有任务要执行,则等待 */
  19:         pthread_mutex_lock(&tpool->queue_lock);
  20:         while(!tpool->queue_head && !tpool->shutdown) {
  21:             pthread_cond_wait(&tpool->queue_ready, &tpool->queue_lock);
  22:         }
  23:         if (tpool->shutdown) {
  24:             pthread_mutex_unlock(&tpool->queue_lock);
  25:             pthread_exit(NULL);
  26:         }
  27:         work = tpool->queue_head;
  28:         tpool->queue_head = tpool->queue_head->next;
  29:         pthread_mutex_unlock(&tpool->queue_lock);
  30: 
  31:         work->routine(work->arg);
  32:         free(work);
  33:     }
  34:     
  35:     return NULL;   
  36: }
  37: 
  38: /*
  39:  * 创建线程池 
  40:  */
  41: int
  42: tpool_create(int max_thr_num)
  43: {
  44:     int i;
  45: 
  46:     tpool = calloc(1, sizeof(tpool_t));
  47:     if (!tpool) {
  48:         printf("%s: calloc failed\n", __FUNCTION__);
  49:         exit(1);
  50:     }
  51:     
  52:     /* 初始化 */
  53:     tpool->max_thr_num = max_thr_num;
  54:     tpool->shutdown = 0;
  55:     tpool->queue_head = NULL;
  56:     if (pthread_mutex_init(&tpool->queue_lock, NULL) !=0) {
  57:         printf("%s: pthread_mutex_init failed, errno:%d, error:%s\n",
  58:             __FUNCTION__, errno, strerror(errno));
  59:         exit(1);
  60:     }
  61:     if (pthread_cond_init(&tpool->queue_ready, NULL) !=0 ) {
  62:         printf("%s: pthread_cond_init failed, errno:%d, error:%s\n", 
  63:             __FUNCTION__, errno, strerror(errno));
  64:         exit(1);
  65:     }
  66:     
  67:     /* 创建工作者线程 */
  68:     tpool->thr_id = calloc(max_thr_num, sizeof(pthread_t));
  69:     if (!tpool->thr_id) {
  70:         printf("%s: calloc failed\n", __FUNCTION__);
  71:         exit(1);
  72:     }
  73:     for (i = 0; i < max_thr_num; ++i) {
  74:         if (pthread_create(&tpool->thr_id[i], NULL, thread_routine, NULL) != 0){
  75:             printf("%s:pthread_create failed, errno:%d, error:%s\n", __FUNCTION__, 
  76:                 errno, strerror(errno));
  77:             exit(1);
  78:         }
  79:         
  80:     }    
  81: 
  82:     return 0;
  83: }
  84: 
  85: /* 销毁线程池 */
  86: void
  87: tpool_destroy()
  88: {
  89:     int i;
  90:     tpool_work_t *member;
  91: 
  92:     if (tpool->shutdown) {
  93:         return;
  94:     }
  95:     tpool->shutdown = 1;
  96: 
  97:     /* 通知所有正在等待的线程 */
  98:     pthread_mutex_lock(&tpool->queue_lock);
  99:     pthread_cond_broadcast(&tpool->queue_ready);
 100:     pthread_mutex_unlock(&tpool->queue_lock);
 101:     for (i = 0; i < tpool->max_thr_num; ++i) {
 102:         pthread_join(tpool->thr_id[i], NULL);
 103:     }
 104:     free(tpool->thr_id);
 105: 
 106:     while(tpool->queue_head) {
 107:         member = tpool->queue_head;
 108:         tpool->queue_head = tpool->queue_head->next;
 109:         free(member);
 110:     }
 111: 
 112:     pthread_mutex_destroy(&tpool->queue_lock);    
 113:     pthread_cond_destroy(&tpool->queue_ready);
 114: 
 115:     free(tpool);    
 116: }
 117: 
 118: /* 向线程池添加任务 */
 119: int
 120: tpool_add_work(void*(*routine)(void*), void *arg)
 121: {
 122:     tpool_work_t *work, *member;
 123:     
 124:     if (!routine){
 125:         printf("%s:Invalid argument\n", __FUNCTION__);
 126:         return -1;
 127:     }
 128:     
 129:     work = malloc(sizeof(tpool_work_t));
 130:     if (!work) {
 131:         printf("%s:malloc failed\n", __FUNCTION__);
 132:         return -1;
 133:     }
 134:     work->routine = routine;
 135:     work->arg = arg;
 136:     work->next = NULL;
 137: 
 138:     pthread_mutex_lock(&tpool->queue_lock);    
 139:     member = tpool->queue_head;
 140:     if (!member) {
 141:         tpool->queue_head = work;
 142:     } else {
 143:         while(member->next) {
 144:             member = member->next;
 145:         }
 146:         member->next = work;
 147:     }
 148:     /* 通知工作者线程,有新任务添加 */
 149:     pthread_cond_signal(&tpool->queue_ready);
 150:     pthread_mutex_unlock(&tpool->queue_lock);
 151: 
 152:     return 0;    
 153: }
 154:     
 155: 

测试代码:

   1: #include <unistd.h>
   2: #include <stdio.h>
   3: #include <stdlib.h>
   4: #include "tpool.h"
   5: 
   6: void *func(void *arg)
   7: {
   8:     printf("thread %d\n", (int)arg);
   9:     return NULL;
  10: }
  11: 
  12: int
  13: main(int arg, char **argv)
  14: {
  15:     if (tpool_create(5) != 0) {
  16:         printf("tpool_create failed\n");
  17:         exit(1);
  18:     }
  19:     
  20:     int i;
  21:     for (i = 0; i < 10; ++i) {
  22:         tpool_add_work(func, (void*)i);
  23:     }
  24:     sleep(2);
  25:     tpool_destroy();
  26:     return 0;
  27: }

这个实现是在调用tpool_destroy之后,仅将当前正在执行的任务完成之后就会退出,我们也可以修改代码使得线程池在执行完任务链表中所有任务后再退出。

分享到:
评论

相关推荐

    C语言实现简单线程池.zip

    在本项目"简单线程池"中,我们将重点探讨如何用C语言在Linux环境下实现这样一个线程池系统,特别是关注其核心组件和设计原则。 首先,线程池的核心概念是线程复用,通过预先创建一组线程,可以避免频繁地创建和销毁...

    C语言实现的简单线程池

    C语言实现的简单线程池

    Linux环境下C语言实现简单线程池.zip

    本教程将深入探讨如何使用C语言在Linux上实现一个简单的线程池。 线程池的基本思想是预先创建一组线程,它们被存储在一个队列中,等待执行任务。当有新的任务到来时,线程池会分配一个空闲的线程来处理这个任务,而...

    C语言实现的线程池.zip

    下面是一个简单的线程池实现框架: 1. 初始化线程池:创建一定数量的工作线程,并初始化任务队列。 2. 添加任务:使用`pthread_mutex_lock()`锁定任务队列,将任务插入队列,然后使用`pthread_cond_signal()`通知...

    linux下C语言实现线程池

    接下来,我们将深入探讨如何在Linux环境下用C语言实现线程池。 首先,我们需要了解线程的基本概念。在C语言中,线程是进程内的一个执行单元,每个线程都有自己的程序计数器、栈和局部变量,但共享全局变量和其他...

    线程池实现,通过C语言实现

    在给定的资源中,"200行C代码实现简单线程池.doc"可能包含了详细的设计和实现步骤,以及如何在实际项目中应用线程池的文档。而"threadpool.c"则是实际的C语言源代码文件,实现了线程池的核心功能。下面我们将探讨...

    VC++ 线程池(ThreadPool)实现

    本文将深入探讨VC++中线程池的实现,并提供一个简单的实现示例。 线程池的基本概念: 线程池是由一组工作线程组成的集合,这些线程预先创建并处于待命状态,等待执行由应用程序提交的任务。当一个任务被提交到...

    Windows(VC doc)下C语言线程池聊天室-服务器-客户端

    在Windows环境下,使用Visual C++ 6.0(简称VC6)进行C语言编程时,可以构建线程池聊天室项目。这个项目涉及到的核心技术包括C语言编程、多线程处理、Socket套接字编程以及文件操作。接下来,我们将详细讨论这些知识...

    基于C语言实现多线程和线程池【100012227】

    综上所述,基于C语言实现多线程和线程池涉及的知识点包括:多线程编程、线程池的设计与实现、TCP/IP协议栈的理解、HTTP协议的处理、DNS异步查询、MySQL C API的使用、数据库连接池的设计、以及数据结构和文件操作。...

    基于UNIX C语言的一种线程池实现.pdf

    UNIX C语言实现的线程池方案,其设计目标非常明确,即提供一个简单、快速、可靠的线程池实现。这一目标背后,是对线程池基本功能的高度概括与具体化。具体而言,线程池应具有以下功能:能够设置线程池中的最小和最大...

    Linux- 用C语言实现的简单Web服务器源代码

    在这个简单的C语言实现中,我们可能会看到以下关键部分: 1. **监听与连接**:Web服务器需要监听特定端口(如80)上的连接请求。使用`socket()`函数创建套接字,`bind()`函数绑定IP地址和端口号,然后用`listen()`...

    c语言一个简单的线程池,实现不超过100行.zip

    这个压缩包中包含了C语言实现的一个简易线程池的完整代码,包括头文件、源文件、资源说明文档和Readme,非常适合初学者进行学习和实践。通过分析和使用这个线程池实现,学习者将能够掌握如何用C语言进行高效的并发...

    linux下c语言实现多线程web服务器

    本项目是针对操作系统课程设计的一个多线程Web服务器,它利用C语言实现了服务器的基本功能,并且引入了线程池的设计思想,以优化性能和资源管理。下面我们将深入探讨这个项目中的关键知识点。 1. **多线程技术**:...

    C语言实现的snmp服务源码

    本文将详细介绍基于C语言实现的SNMP服务源码以及与之相关的知识点。 首先,C语言实现的SNMP服务源码意味着开发者使用C语言编写了处理SNMP报文、解析请求、构建响应等功能的代码。这涉及到对SNMP协议的深入理解,...

    Threadpool 轻量型 基于 pthread 实现的简单线程池 C语言

    3. **线程池的创建与初始化**:在C语言实现的线程池中,首先需要初始化线程池,这可能涉及到线程的创建、任务队列的初始化以及一些配置参数的设置,如最大线程数、线程优先级等。 4. **任务的提交与执行**:线程池...

    C实现线程池

    ### C语言实现线程池 #### 一、概述 在多线程编程中,线程池是一种常用的资源管理技术,可以有效地控制运行中的线程数量,重用已创建的线程,减少创建和销毁线程的开销,提高响应速度和处理能力。本文将详细介绍...

    linux线程池创建c实现

    简单的说,如果一个应用需要频繁的创建和销毁线程,而任务执行的时间又非常短,这样线程创建和销毁的带来的开销就不容忽视,这时也是线程池该出场的机会了。如果线程创建和销毁时间相比任务执行时间可以忽略不计,则...

    C语言实现一个简单的thread_pool.zip

    本文将深入探讨如何使用C语言实现一个简单的线程池。线程池的基本思想是预先创建一组线程,当有任务需要执行时,这些线程会被复用而不是每次创建新的线程,从而减少了线程创建和销毁的开销。 标题"\"C语言实现一个...

    zl_threadpool, Linux平台下C (C 98、C 03、C 11)实现的线程池.zip

    《Linux平台下C语言实现线程池:zl_threadpool》 在现代计算机系统中,多线程编程已经成为提升效率和优化资源使用的关键技术。线程池作为一种管理线程的机制,能够有效地解决频繁创建和销毁线程所带来的开销,提高...

    C线程池简单应用层实现

    总结来说,这个C语言实现的线程池展示了如何结合多种技术来构建一个高效的多线程任务调度系统。双向循环链表提供了灵活的任务管理,带参宏简化了代码,管道和Epoll实现了线程间的通信,而二级指针则允许传递和修改...

Global site tag (gtag.js) - Google Analytics