加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_宿迁站长网 (https://www.0527zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

linux线程池c的实现原理,Linux-C实现线程池

发布时间:2022-10-21 13:32:07 所属栏目:Linux 来源:网络
导读: 文章目录

?池是一组资源的集合,这组资源在服务器启动之初就被创建和初始化,这称为静态资源分配。它避免了服务器对内核的频繁访问,提高了效率。
?常见的池有进程池,线程池,内存池

文章目录

?池是一组资源的集合,这组资源在服务器启动之初就被创建和初始化,这称为静态资源分配。它避免了服务器对内核的频繁访问,提高了效率。

?常见的池有进程池,线程池,内存池

内存池

?先申请一定数量,大小相等的内存块备用。有新的内存需求时,就从内存池中分出一部分内存块,若内存不足则继续申请新的内存。内存池使内存分配效率得到提升

进程池

?进程池线先由服务器创建一组子进程,子进程数量应和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;

}

(编辑:云计算网_宿迁站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!