基于上一个博客的研究,接下来针对具体的代码进行分析。
程序设计流程:
线程池初始化(n个线程) ----> 往线程池仍任务(n个任务) ----> 销毁线程池(n个线程)
pool_init(int pnt) pool_add_worker pool_destroy()
( (void *(*process) (void *arg), void *arg))
分为以下的步骤去熟悉整体的代码和细节代码
1 其中先熟悉其主要结构体的成员
/* all tasks in the linked list recalled function for task */ typedef struct worker { void *(*process) (void *arg); /*recalled function*/ void *arg; struct worker *next; } CThread_worker; typedef struct cthread_pool { pthread_mutex_t queue_lock; pthread_cond_t queue_ready; /*head for task*/ CThread_worker *queue_head; pthread_t *threadid; /*max number of pthread*/ int max_thread_num; /*current queue number*/ int cur_queue_size; /*whether to destroy pool*/ int shutdown; } CThread_pool;
2 pool_init(int max_thread_num)程序实现
pool_init(int max_thread_num)
{ int i;
pool = (CThread_pool *) malloc (sizeof (CThread_pool)); pthread_mutex_init (&(pool->queue_lock), NULL); pthread_cond_init (&(pool->queue_ready), NULL); pool->queue_head = NULL; pool->max_thread_num = max_thread_num; pool->cur_queue_size = 0; pool->shutdown = 0; pool->threadid = (pthread_t *) malloc (max_thread_num * sizeof (pthread_t));
for (i = 0; i < max_thread_num; i++) pthread_create (&(pool->threadid[i]), NULL, thread_routine,NULL); }
void * thread_routine (void *arg) { printf ("starting thread 0x%lu\n", pthread_self ()); while (1) { /* if the size of waiting list, do not destroy pool waiting to do */ pthread_mutex_lock (&(pool->queue_lock)); while (pool->cur_queue_size == 0 && !pool->shutdown) { printf ("thread 0x%lu is waiting\n", pthread_self ()); pthread_cond_wait (&(pool->queue_ready), &(pool->queue_lock)); } if (pool->shutdown) { pthread_mutex_unlock (&(pool->queue_lock)); printf ("thread 0x%lu will exit\n", pthread_self ()); pthread_exit (NULL); } printf ("thread 0x%lu is starting to work\n", pthread_self ()); assert (pool->cur_queue_size != 0); assert (pool->queue_head != NULL); /*head - 1, fetch the head of linked list*/ pool->cur_queue_size--; CThread_worker *worker = pool->queue_head; pool->queue_head = worker->next; pthread_mutex_unlock (&(pool->queue_lock)); /*recalled function*/ (*(worker->process)) (worker->arg); free (worker); worker = NULL; } pthread_exit (NULL); }
cur_queue_size在仍任务时++,在创建线程时--,
并且 CThread_worker *worker = pool->queue_head,
xy(x == pool->queue_head)
pool->queue_head = worker->next <====> pool->queue_head = pool->queue_head->next
y 增加一个y作为pool最新的链表头。
借助遍历链表说明以上情况:
while (h->next != NULL) { h = h->next; printf("%d ", h->score); }
abcdefghi
a->head = a,
a->nex = b,c,d,e,f,g,h,i
3. 销毁线程链表
int pool_destroy () { int i; pool->shutdown = 1; /*ask all pthreads*/ pthread_cond_broadcast (&(pool->queue_ready)); for (i = 0; i < pool->max_thread_num; i++) pthread_join (pool->threadid[i], NULL); free (pool->threadid); /*destroy waiting list*/ CThread_worker *head = NULL; while (pool->queue_head != NULL) { head = pool->queue_head; pool->queue_head = pool->queue_head->next; free (head); if (pool->queue_head == NULL) break; } /*lock free*/ pthread_mutex_destroy(&(pool->queue_lock)); pthread_cond_destroy(&(pool->queue_ready)); free (pool); pool=NULL; return 0; }
while (pool->queue_head != NULL) { head = pool->queue_head; pool->queue_head = pool->queue_head->next; free (head); if (pool->queue_head == NULL) break; }
pool : abcdefghi
pool->queue_head = a
pool->queue_head->next = b c d e f g h i
附加链表的具体知识:
该线程池利用到了单链表结构,区分顺序表结构,因前者随机物理内存位置存储数据,后者顺序存储。
Life is mess, don't let mess mess us.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了