半驻留高性能线程池例子

71 篇文章 3 订阅
19 篇文章 0 订阅

http://www.oschina.net/code/snippet_568966_43274

acl 跨平台网络通信与服务器框架的线程池模块是一个半驻留式的高性能线程池库,使用简单稳定,可以指定最大线程数量及线程空闲时间,按需分配,当负载高时可以启动较多的线程处理任务(不超过设定的最大线程数限制),当没有负载时,空闲线程在达到空闲阀值后自动退出,本示例为了一个使用 acl 库中 lib_acl (C库)的线程池例子,在 acl 库的位置:acl\samples\thread\thread_pool3
acl 库下载:http://sourceforge.net/projects/acl/
acl 库的 github:https://github.com/zhengshuxin/acl
更多技术文章:http://zsxxsz.iteye.com
标签: acl

代码片段(1)[全屏查看所有代码]

1. [代码][C/C++]代码     跳至 [1] [全屏预览]

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
#include "lib_acl.h"
#include <assert.h>
 
/**
  * 用户自定义数据结构
  */
typedef struct THREAD_CTX {
     acl_pthread_pool_t *thr_pool;
     int   i;
} THREAD_CTX;
 
/* 全局性静态变量 */
static acl_pthread_pool_t *__thr_pool = NULL;
 
/* 线程局部存储变量(C99支持此种方式声明,方便许多) */
static __thread unsigned int __local = 0;
 
static void free_buf_fn( void *arg)
{
     ACL_VSTRING *buf = (ACL_VSTRING*) arg;
 
     printf ( ">> current thread id=%u, buf = %s\r\n" ,
         (unsigned int ) acl_pthread_self(), acl_vstring_str(buf));
     acl_vstring_free(buf);
}
 
static void worker_thread( void *arg)
{
     THREAD_CTX *ctx = (THREAD_CTX*) arg; /* 获得用户自定义对象 */
     unsigned int   i = 0;
     static __thread ACL_VSTRING *buf1 = NULL;
     static __thread ACL_VSTRING *buf2 = NULL;
 
     /* 仅是验证参数传递过程 */
     assert (ctx->thr_pool == __thr_pool);
 
     if (buf1 == NULL)
         buf1 = acl_vstring_alloc(256);
     if (buf2 == NULL)
         buf2 = acl_vstring_alloc(256);
 
     acl_vstring_sprintf(buf1, "buf1: tid=%u" ,
         (unsigned int ) acl_pthread_self());
     acl_vstring_sprintf(buf2, "buf2: tid=%u" ,
         (unsigned int ) acl_pthread_self());
     /* 注册函数,当该线程退出时自动释放 buf 内存空间 */
     acl_pthread_atexit_add(buf1, free_buf_fn);
     acl_pthread_atexit_add(buf2, free_buf_fn);
 
     while (i < 5) {
         if (__local != i)
             acl_msg_fatal( "__local=%d invalid" , __local);
         printf ( "thread id=%u, i=%d, __local=%d\r\n" ,
             (unsigned int ) acl_pthread_self(), ctx->i, __local);
         i++;
         /* 在本线程中将线程局部变量加1 */
         __local++;
         sleep(1);
     }
 
     acl_myfree(ctx);
 
     /* 至此,该工作线程进入空闲状态,直到空闲超时退出 */
}
 
static int on_thread_init( void *arg)
{
     const char *myname = "on_thread_init" ;
     acl_pthread_pool_t *thr_pool = (acl_pthread_pool_t*) arg;
 
     /* 判断一下,仅是为了验证参数传递过程 */
     assert (thr_pool == __thr_pool);
     printf ( "%s: thread(%u) init now\r\n" , myname, (unsigned int ) acl_pthread_self());
 
     /* 返回0表示继续执行该线程获得的新任务,返回-1表示停止执行该任务 */
     return (0);
}
 
static void on_thread_exit( void *arg)
{
     const char *myname = "on_thread_exit" ;
     acl_pthread_pool_t *thr_pool = (acl_pthread_pool_t*) arg;
 
     /* 判断一下,仅是为了验证参数传递过程 */
     assert (thr_pool == __thr_pool);
     printf ( "%s: thread(%u) exit now\r\n" , myname, (unsigned int ) acl_pthread_self());
}
 
static void run_thread_pool(acl_pthread_pool_t *thr_pool)
{
     THREAD_CTX *ctx;  /* 用户自定义参数 */
 
     /* 设置全局静态变量 */
     __thr_pool = thr_pool;
 
     /* 设置线程开始时的回调函数 */
     ( void ) acl_pthread_pool_atinit(thr_pool, on_thread_init, thr_pool);
 
     /* 设置线程退出时的回调函数 */
     ( void ) acl_pthread_pool_atfree(thr_pool, on_thread_exit, thr_pool);
 
     ctx = (THREAD_CTX*) acl_mycalloc(1, sizeof (THREAD_CTX));
     assert (ctx);
     ctx->thr_pool = thr_pool;
     ctx->i = 0;
 
     /**
     * 向线程池中添加第一个任务,即启动第一个工作线程
     * @param wq 线程池句柄
     * @param worker_thread 工作线程的回调函数
     * @param event_type 此处写0即可
     * @param ctx 用户定义参数
     */
     acl_pthread_pool_add(thr_pool, worker_thread, ctx);
     sleep(1);
 
     ctx = (THREAD_CTX*) acl_mycalloc(1, sizeof (THREAD_CTX));
     assert (ctx);
     ctx->thr_pool = thr_pool;
     ctx->i = 1;
     /* 向线程池中添加第二个任务,即启动第二个工作线程 */
     acl_pthread_pool_add(thr_pool, worker_thread, ctx);
}
 
static void main_thread_atexit( void *arg)
{
     ACL_VSTRING *buf = (ACL_VSTRING*) arg;
 
     printf ( "main thread exit now, tid=%u, buf=%s\r\n" ,
         (unsigned int ) acl_pthread_self(), acl_vstring_str(buf));
     printf ( "in the main thread_atexit, input any key to exit\r\n" );
     getchar ();
}
 
static acl_pthread_pool_t *thr_pool_create( int threads, int timeout)
{
     acl_pthread_pool_attr_t attr;
     acl_pthread_pool_t *thr_pool;
 
     acl_pthread_pool_attr_init(&attr);
     acl_pthread_pool_attr_set_threads_limit(&attr, threads);
     acl_pthread_pool_attr_set_idle_timeout(&attr, timeout);
 
     /* 创建半驻留线程句柄 */
     thr_pool = acl_pthread_pool_create(&attr);
     assert (thr_pool);
     return (thr_pool);
}
 
typedef struct {
     ACL_VSTREAM *fp;
     int  i;
} RUN_CTX;
static acl_pthread_mutex_t __mutex;
static int  __i = 0;
static void run_thread( void *arg)
{
     RUN_CTX *ctx = (RUN_CTX*) arg;
 
     acl_pthread_mutex_lock(&__mutex);
     if (0)
         acl_vstream_fprintf(ctx->fp, "hello world, id: %d, i: %d\n" , ctx->i, __i++);
     else
         __i++;
     acl_pthread_mutex_unlock(&__mutex);
     acl_myfree(ctx);
}
 
static void test_thread_pool( void )
{
     acl_pthread_pool_t *thr_pool;
     ACL_VSTREAM *fp = acl_vstream_fopen( "test.log" , O_WRONLY | O_CREAT, 0600, 4096);
     int   i;
 
     acl_pthread_mutex_init(&__mutex, NULL);
     thr_pool = acl_thread_pool_create(100, 10);
 
     for (i = 0; i < 1000000; i++) {
         RUN_CTX *ctx = (RUN_CTX*) acl_mymalloc( sizeof (RUN_CTX));
         ctx->fp = fp;
         ctx->i = i;
         acl_pthread_pool_add(thr_pool, run_thread, ctx);
     }
 
     acl_pthread_pool_destroy(thr_pool);
     acl_pthread_mutex_destroy(&__mutex);
     acl_vstream_close(fp);
     printf ( "last i: %d\r\n" , __i);
}
 
int main( int argc acl_unused, char *argv[] acl_unused)
{
     acl_pthread_pool_t *thr_pool;
     int  max_threads = 20;  /* 最多并发20个线程 */
     int  idle_timeout = 10; /* 每个工作线程空闲10秒后自动退出 */
     static __thread ACL_VSTRING *buf = NULL;
 
     if (1) {
         test_thread_pool();
         exit (0);
     }
 
     buf = acl_vstring_alloc(256);
     acl_vstring_sprintf(buf, "in main thread, id=%u" ,
         (unsigned int ) acl_pthread_self());
     acl_pthread_atexit_add(buf, main_thread_atexit);
 
 
     thr_pool = thr_pool_create(max_threads, idle_timeout);
     run_thread_pool(thr_pool);
 
     if (0) {
         /* 如果立即运行 acl_pthread_pool_destroy,则由于调用了线程池销毁函数,
          * 主线程便立刻通知空闲线程退出,所有空闲线程不必等待空闲超时时间便可退出,
          */
         printf ( "> wait all threads to be idle and free thread pool\r\n" );
         /* 立即销毁线程池 */
         acl_pthread_pool_destroy(thr_pool);
     } else {
         /* 因为不立即调用 acl_pthread_pool_destroy,所有所有空闲线程都是当空闲
          * 超时时间到达后才退出
          */
         while (1) {
             int   ret;
 
             ret = acl_pthread_pool_size(thr_pool);
             if (ret == 0)
                 break ;
             printf ( "> current threads in thread pool is: %d\r\n" , ret);
             sleep(1);
         }
         /* 线程池中的工作线程数为0时销毁线程池 */
         printf ( "> all worker thread exit now\r\n" );
         acl_pthread_pool_destroy(thr_pool);
     }
 
     /* 主线程等待用户在终端输入任意字符后退出 */
     printf ( "> enter any key to exit\r\n" );
     getchar ();
 
     return (0);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值