如何在Linux下实现你的线程池(Step By Step,Pthread)
2012-09-28 20:39 Haippy 阅读(3796) 评论(1) 编辑 收藏 举报200行C代码就可以实现线程池?开玩笑吧?不,告诉你,我是认真的,200行C代码真的可以实现一个简单可用的线程池!!!
首先,你应该知道 PThread 吧,如果不知道,那你怎么穿越到我这个页面的,你应该先去看看维基,或者这个,这个,什么,你想在Windows系统下使用 pthread,那你应该去这个页面看看啦,亲!咱们先看实现代码吧,木有注释,木有例子 ^0^,下次再给例子,请留意了,今天就到这里吧~~~
/* * ============================================================================= * * Filename: tiny-threadpool.h * * Description: tiny threadpool implementation in c. * * Created: 09/28/2012 07:37:30 PM * * Author: Fu Haiping (forhappy), haipingf@gmail.com * Company: ICT ( Institute Of Computing Technology, CAS ) * * ============================================================================= */ #ifndef TINY_THREADPOOL_H #define TINY_THREADPOOL_H #include <pthread.h> typedef struct _tthreadpool_s tthreadpool_t; typedef struct _tthread_s tthread_t; typedef struct _tjob_s tjob_t; struct _tthreadpool_s { tthread_t *threads; tjob_t *jobs; int num_jobs; int num_threads; pthread_mutex_t jobs_mutex; pthread_mutex_t num_jobs_mutex; pthread_cond_t jobs_not_empty_cond; pthread_cond_t jobs_not_full_cond; }; struct _tthread_s { pthread_t thread_id; tthreadpool_t *pool; tthread_t *prev; tthread_t *next; int killed; }; struct _tjob_s { void (*job_function)(tjob_t *job); void *user_data; tjob_t *prev; tjob_t *next; }; extern int tthreadpool_init(tthreadpool_t *pool, int numWorkers); extern void tthreadpool_shutdown(tthreadpool_t *pool); extern void tthreadpool_add_job(tthreadpool_t *pool, tjob_t *job); extern void tthreadpool_add_job_ex(tthreadpool_t *pool, tjob_t *job); extern void tthreadpool_wait(tthreadpool_t *pool); #endif // TINY_THREADPOOL_H
/* * ============================================================================= * * Filename: tiny-threadpool.c * * Description: tiny threadpool implementation in c. * * Created: 09/28/2012 07:37:20 PM * * Author: Fu Haiping (forhappy), haipingf@gmail.com * Company: ICT ( Institute Of Computing Technology, CAS ) * * ============================================================================= */ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "tiny-threadpool.h" #define ADD_THREAD(item, list) { \ item->prev = NULL; \ item->next = list; \ list = item; \ } #define REMOVE_JOB(item, list) { \ if (item->prev != NULL) item->prev->next = item->next; \ if (item->next != NULL) item->next->prev = item->prev; \ if (list == item) list = item->next; \ item->prev = item->next = NULL; \ } static void *thread_function(void *ptr) { tthread_t *thread = (tthread_t *)ptr; tjob_t *job; while (1) { pthread_mutex_lock(&thread->pool->num_jobs_mutex); pthread_mutex_lock(&thread->pool->jobs_mutex); while (thread->pool->jobs == NULL) { pthread_cond_wait(&thread->pool->jobs_not_empty_cond, &thread->pool->jobs_mutex); } job = thread->pool->jobs; if (job != NULL) { REMOVE_JOB(job, thread->pool->jobs); thread->pool->num_jobs--; pthread_cond_signal(&thread->pool->jobs_not_full_cond); } pthread_mutex_unlock(&thread->pool->jobs_mutex); pthread_mutex_unlock(&thread->pool->num_jobs_mutex); if (thread->killed) break; if (job == NULL) continue; job->job_function(job); } free(thread); pthread_exit(NULL); } int tthreadpool_init(tthreadpool_t *pool, int num_threads) { int i = 0; tthread_t *thread; pthread_cond_t blank_cond = PTHREAD_COND_INITIALIZER; pthread_mutex_t blank_mutex = PTHREAD_MUTEX_INITIALIZER; if (num_threads < 1) num_threads = 1; memset(pool, 0, sizeof(*pool)); memcpy(&pool->jobs_mutex, &blank_mutex, sizeof(pool->jobs_mutex)); memcpy(&pool->num_jobs_mutex, &blank_mutex, sizeof(pool->num_jobs_mutex)); memcpy(&pool->jobs_not_empty_cond, &blank_cond, sizeof(pool->jobs_not_empty_cond)); memcpy(&pool->jobs_not_full_cond, &blank_cond, sizeof(pool->jobs_not_full_cond)); pool->num_threads = num_threads; pool->num_jobs = 0; for (i = 0; i < num_threads; i++) { if ((thread = malloc(sizeof(tthread_t))) == NULL) { fprintf(stderr, "Failed to allocate threads"); return -1; } memset(thread, 0, sizeof(tthread_t)); thread->pool = pool; if (pthread_create(&thread->thread_id, NULL, thread_function, (void *)thread)) { fprintf(stderr, "Failed to start all threads"); free(thread); return -1; } ADD_THREAD(thread, thread->pool->threads); } return 0; } void tthreadpool_shutdown(tthreadpool_t *pool) { tthread_t *thread = NULL; for (thread = pool->threads; thread != NULL; thread = thread->next) { thread->killed = 1; } pthread_mutex_lock(&pool->jobs_mutex); pool->threads = NULL; pool->jobs = NULL; pthread_cond_broadcast(&pool->jobs_not_empty_cond); pthread_mutex_unlock(&pool->jobs_mutex); } void tthreadpool_add_job(tthreadpool_t *pool, tjob_t *job) { pthread_mutex_lock(&pool->jobs_mutex); ADD_THREAD(job, pool->jobs); pthread_cond_signal(&pool->jobs_not_empty_cond); pthread_mutex_unlock(&pool->jobs_mutex); } void tthreadpool_add_job_ex(tthreadpool_t *pool, tjob_t *job) { pthread_mutex_lock(&pool->jobs_mutex); while(pool->num_jobs == 2 * pool->num_threads) { pthread_cond_wait(&pool->jobs_not_full_cond, &pool->jobs_mutex); } ADD_THREAD(job, pool->jobs); pool->num_jobs++; pthread_cond_signal(&pool->jobs_not_empty_cond); pthread_mutex_unlock(&pool->jobs_mutex); } void tthreadpool_wait(tthreadpool_t *pool) { tthread_t *thread = NULL; for (thread = pool->threads; thread != NULL; thread = thread->next) { pthread_join(thread->thread_id, NULL); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗