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:
相关推荐
在本项目"简单线程池"中,我们将重点探讨如何用C语言在Linux环境下实现这样一个线程池系统,特别是关注其核心组件和设计原则。 首先,线程池的核心概念是线程复用,通过预先创建一组线程,可以避免频繁地创建和销毁...
C语言实现的简单线程池
本教程将深入探讨如何使用C语言在Linux上实现一个简单的线程池。 线程池的基本思想是预先创建一组线程,它们被存储在一个队列中,等待执行任务。当有新的任务到来时,线程池会分配一个空闲的线程来处理这个任务,而...
下面是一个简单的线程池实现框架: 1. 初始化线程池:创建一定数量的工作线程,并初始化任务队列。 2. 添加任务:使用`pthread_mutex_lock()`锁定任务队列,将任务插入队列,然后使用`pthread_cond_signal()`通知...
接下来,我们将深入探讨如何在Linux环境下用C语言实现线程池。 首先,我们需要了解线程的基本概念。在C语言中,线程是进程内的一个执行单元,每个线程都有自己的程序计数器、栈和局部变量,但共享全局变量和其他...
在给定的资源中,"200行C代码实现简单线程池.doc"可能包含了详细的设计和实现步骤,以及如何在实际项目中应用线程池的文档。而"threadpool.c"则是实际的C语言源代码文件,实现了线程池的核心功能。下面我们将探讨...
本文将深入探讨VC++中线程池的实现,并提供一个简单的实现示例。 线程池的基本概念: 线程池是由一组工作线程组成的集合,这些线程预先创建并处于待命状态,等待执行由应用程序提交的任务。当一个任务被提交到...
在Windows环境下,使用Visual C++ 6.0(简称VC6)进行C语言编程时,可以构建线程池聊天室项目。这个项目涉及到的核心技术包括C语言编程、多线程处理、Socket套接字编程以及文件操作。接下来,我们将详细讨论这些知识...
综上所述,基于C语言实现多线程和线程池涉及的知识点包括:多线程编程、线程池的设计与实现、TCP/IP协议栈的理解、HTTP协议的处理、DNS异步查询、MySQL C API的使用、数据库连接池的设计、以及数据结构和文件操作。...
UNIX C语言实现的线程池方案,其设计目标非常明确,即提供一个简单、快速、可靠的线程池实现。这一目标背后,是对线程池基本功能的高度概括与具体化。具体而言,线程池应具有以下功能:能够设置线程池中的最小和最大...
在这个简单的C语言实现中,我们可能会看到以下关键部分: 1. **监听与连接**:Web服务器需要监听特定端口(如80)上的连接请求。使用`socket()`函数创建套接字,`bind()`函数绑定IP地址和端口号,然后用`listen()`...
这个压缩包中包含了C语言实现的一个简易线程池的完整代码,包括头文件、源文件、资源说明文档和Readme,非常适合初学者进行学习和实践。通过分析和使用这个线程池实现,学习者将能够掌握如何用C语言进行高效的并发...
本项目是针对操作系统课程设计的一个多线程Web服务器,它利用C语言实现了服务器的基本功能,并且引入了线程池的设计思想,以优化性能和资源管理。下面我们将深入探讨这个项目中的关键知识点。 1. **多线程技术**:...
本文将详细介绍基于C语言实现的SNMP服务源码以及与之相关的知识点。 首先,C语言实现的SNMP服务源码意味着开发者使用C语言编写了处理SNMP报文、解析请求、构建响应等功能的代码。这涉及到对SNMP协议的深入理解,...
3. **线程池的创建与初始化**:在C语言实现的线程池中,首先需要初始化线程池,这可能涉及到线程的创建、任务队列的初始化以及一些配置参数的设置,如最大线程数、线程优先级等。 4. **任务的提交与执行**:线程池...
### C语言实现线程池 #### 一、概述 在多线程编程中,线程池是一种常用的资源管理技术,可以有效地控制运行中的线程数量,重用已创建的线程,减少创建和销毁线程的开销,提高响应速度和处理能力。本文将详细介绍...
简单的说,如果一个应用需要频繁的创建和销毁线程,而任务执行的时间又非常短,这样线程创建和销毁的带来的开销就不容忽视,这时也是线程池该出场的机会了。如果线程创建和销毁时间相比任务执行时间可以忽略不计,则...
本文将深入探讨如何使用C语言实现一个简单的线程池。线程池的基本思想是预先创建一组线程,当有任务需要执行时,这些线程会被复用而不是每次创建新的线程,从而减少了线程创建和销毁的开销。 标题"\"C语言实现一个...
《Linux平台下C语言实现线程池:zl_threadpool》 在现代计算机系统中,多线程编程已经成为提升效率和优化资源使用的关键技术。线程池作为一种管理线程的机制,能够有效地解决频繁创建和销毁线程所带来的开销,提高...
总结来说,这个C语言实现的线程池展示了如何结合多种技术来构建一个高效的多线程任务调度系统。双向循环链表提供了灵活的任务管理,带参宏简化了代码,管道和Epoll实现了线程间的通信,而二级指针则允许传递和修改...