linux线程池c的实现原理,Linux-C实现线程池
池
?池是一组资源的集合,这组资源在服务器启动之初就被创建和初始化,这称为静态资源分配。它避免了服务器对内核的频繁访问,提高了效率。
?常见的池有进程池,线程池,内存池
内
文章目录 池 ?池是一组资源的集合,这组资源在服务器启动之初就被创建和初始化,这称为静态资源分配。它避免了服务器对内核的频繁访问,提高了效率。 ?常见的池有进程池,线程池,内存池 内存池 ?先申请一定数量,大小相等的内存块备用。有新的内存需求时,就从内存池中分出一部分内存块,若内存不足则继续申请新的内存。内存池使内存分配效率得到提升 进程池 ?进程池线先由服务器创建一组子进程,子进程数量应和CPU数量差不多。所有子程序具有相同的属性,运行着同样的代码 线程池 概念 ?在Linux中线程实际上是由轻量级进程实现的。线程的创建和清理都需要耗费时间和系统资源,当处理高并发时,线程池就有必要引入了。 ?线程池提升了多线程程序的性能线程池linux,因为线程池中线程都是现成且可重复使用的。理想的线程池能够合理地动态调节池内线程数量 ?线程池是典型的生产者消费者同步问题,主程序不定时将任务任务添加到一个队列中。池中多个工作线程同时执行出队操作(需保证同一时刻只能一个线程出队成功)。这时候生产者是主程序(用于生产任务),消费者是工作线程(用于执行任务) 组成结构 ?线程池主要包括4个部分: 线程管理器:用于创建并管理线程池 工作线程:线程池中实际执行任务的线程,在创建线程池后会创建好固定数目的线程在池中 任务接口:每个任务必须实现的接口。当队列中有任务时,被池中线程执行,把任务抽象成一个接口,可以做到线程池与具体任务无关 任务队列:用于存放没有处理的任务 应用 ?主要应用于需要大量线程来完成任务且任务时间较短,例如Web服务器完成网页请求。或者是突发性的大量请求 代码实现 test.h文件: #include #include #include #include //任务接口(节点) struct Work { void* (*func) (void *arg); void *arg; Work *next; }; //线程池中线程执行的回掉函数 void* thread_poll_func(void *arg); //线程池 struct thread_poll{ //任务队列 Work *head; //线程指针 pthread_t *pd; //条件变量和锁 pthread_mutex_t mutex; pthread_cond_t cond; //线程池是否被销毁 bool shutdown; //线程池中线程的总量 int pthread_num; //当前任务队列中任务数量 int work_num; //初始化函数 thread_poll(int pthread_num) { this -> pthread_num = pthread_num; this -> work_num = 0; this -> shutdown = 0; pthread_mutex_init(&this ->mutex, NULL); pthread_cond_init(&this -> cond, NULL); this -> head = NULL; pd = (pthread_t *)malloc(sizeof(pthread_t) * pthread_num); for (int i = 0; i < pthread_num; i++) { pthread_create(&this -> pd[i], NULL, thread_poll_func, this); } } //向线程池投递任务 void add_work(Work *work); //销毁线程池 int del(); }; test.cpp文件: #include "test.h" //线程池中线程执行的回掉函数 void* thread_poll_func(void *arg) { thread_poll *t = (thread_poll *)arg; while(1) { //上锁 pthread_mutex_lock(&t -> mutex); //循环等待接收任务 while(!(t -> work_num) && !(t -> shutdown)) { pthread_cond_wait(&t -> cond, &t -> mutex); } //如果线程池被销毁 if (t -> shutdown) { //解锁并退出线程 pthread_mutex_unlock(&t -> mutex); pthread_exit(0); } //取出队首任务 t -> work_num --; Work *p = t -> head; t -> head = p -> next; //解锁 pthread_mutex_unlock(&t -> mutex); //执行任务回掉函数 (p -> func)(p -> arg); //释放该任务空间 free(p); } } //向线程池投递任务 void thread_poll::add_work(Work *work) { pthread_mutex_lock(&this -> mutex); //将任务加入到等待队列 Work *p = this -> head; if (p == NULL) { this -> head = work; } else { while(p -> next != NULL) { p = p -> next; } p -> next = work; } this -> work_num ++; pthread_mutex_unlock(&this -> mutex); //唤醒一个等待线程 pthread_cond_signal(&this -> cond); } //销毁线程池 int thread_poll::del() { if (this -> shutdown) { return -1; } this -> shutdown = 1; //唤醒所有线程 pthread_cond_broadcast(&this -> cond); //等待所有线程结束,避免僵尸线程 for (int i = 0; i < this -> pthread_num; i++) { pthread_join(this -> pd[i], NULL); } //释放掉所有线程标识符 free(pd); //销毁任务队列的所有任务 Work *p = this -> head; while(p != NULL) { p = this -> head; this -> head = p -> next; free(p); } //销毁条件变量和锁 pthread_cond_destroy(&this -> cond); pthread_mutex_destroy(&this -> mutex); return 0; } //任务的回掉函数 void* myfunc(void *arg) { printf("%d\n", *(int *)arg); return NULL; } int main () { thread_poll poll(3); int *nuu = (int *)malloc(sizeof(int) * 10); for (int i = 0; i < 10; i++) { nuu[i] = i; Work *work = (Work *)malloc(sizeof(Work)); work -> next = NULL; work -> func = myfunc; work -> arg = (void *)&nuu[i]; poll.add_work(work); } sleep(5); poll.del(); free(nuu); return 0; } (编辑:92站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |