美文网首页
线程池的原理与C语言实现

线程池的原理与C语言实现

作者: 鹏_921010 | 来源:发表于2021-12-21 12:57 被阅读0次

网络数据的处理流程:

1. 检测IO事件是否就绪(可读可写)   epoll 等多路复用

2.对IO进行读写                                recv/send

3.对数据进程解析与操作                  parser()

池式结构:1.连接池  2.线程池 3.内存池 4.异步请求池

为什么需要线程池?在哪些情况下我们会使用到线程池?

阻塞调用(阻塞IO调用、等待资源);耗时的计算(读写文件、复杂的计算);高密度任务(高并发低延时的网络IO请求)

面临以上情况时都去临时创建线程,这样的问题:

创建了太多的线程,系统资源就会被浪费,而且会浪费时间去创建和销毁线程:创建线程太慢,导致执行任务结果返回过慢;销毁线程太慢,可能会影响别的进程使用资源。

所以:创建多个线程,放在池子(管理组件)里不销毁,用的时候就把任务丢给池子里的线程去执行,这就是线程池。那么问题来了,任务由谁产生(生产者),如何丢给线程池的某个线程(消费者)?这问题需要从一下几个方面:

1) 生产者采用什么方式与消费者同步? 2) 任务如何保存? 3) 生产者之间的同步方式,消费者之间的同步方式?

线程池的尺寸设计多大合适?

CPU 密集型的: thread size = N + 1;

IO 密集型的: thread size = 2*N + 1;

当然这不是绝对的,所以在 mariadb 的线程池是可以动态调整这个尺寸的。

线程池:不需要在每次创建线程,避免了线程频繁的创建和销毁

线程池分为三部分: 执行队列(线程) 任务队列(任务) 管理组件

作用: IO 处理的时候 日志处理可以使用线程池

线程共享的环境包括: 进程代码段、进程的公有数据、进程打开的文件描述符,信号处理器、进程的当前目录和进程用户ID 和进程组 ID

每个线程私有的资源包括: 线程 id、寄存器组的值、线程的栈、 errno、线程的信号屏蔽码、线程的优先级

调度实体:使用PCB 进程控制块描述线程实际上也是使用pcb 描述,只是 pcb 的某些变量分别由进程还是线程处理进程是资源分配的最小单元,线程是任务调度的最小单元

多进程:进程的创建需要分配虚拟地址空间、页表、物理内存等;

info thread 查看线程信息 b dothing 跳转到某个函数 bt 查看调用堆栈

b lineno 打断点 c 继续执行

1. 线程不是无限制创建的,而且线程切换是消耗 CPU 资源的

2. 线程的创建和销毁消耗 CPU 资源

3.线程池数量:线程池、 IO 密集型的: thread size = 2*N + 1;一般为 2*cpu 数量

以下是简单版线程池:(我在网上看到一个c的写的线程池:https://github.com/Pithikos/C-Thread-Pool 看到gitbub的一个线程池)

线程池数据结构:

执行队列:

向线程池里抛任务:

在进入任务调度之前空闲数量 = 总的线程数量

线程空闲状态统计,占用总的线程个数的比例,进行统计,对线程池增加和释放线程

100 个任务 5 个线程之间来回切换已经能够处理的,那么就不需要创建 10 个线程

问题:

a. 多个线程同时在一个任务队列中取任务? 加锁,取任务是临界资源

b. 当任务不足时,线程的状态? 条件变量 condition,  条件等待,队列不为空时。

int nready = epoll_wait();

for(i=0;i<nready;i++){

#if 0

a.  recv() ; parser(); send()  --a--纯内存操作是OK的

#elif 0

b. task = fd;   --b--如果fd操作的花费时间长的话,可以这样操作,但是b有一个致命的问题:多线程公用一个fd的现象。可能一个线程正在准备数据,另外一个线程close(fd),脏数据等问题。解法:可以参照协程的做法

push_task(task); //抛给线程、池等

#else

c recv(fd, buffer, sizeof(buffer)); push_task(buffer)   --c--业务比较复杂的话使用

#endif

}

检测IO: 可以放在多个线程,epoll_wait() 放在多个线程

读写IO: 可以放在多个线程

解析数据:可以放在多个线程

小结:

线程池说白了,就是提前分配好工人,然后将任务放到任务队列中,让所有的工人去干活。如果要在干活的时候在去创建线程,销毁线程,在创建和销毁的时候是很消耗资源的。将线程提前做好,然后统一销毁就提高了效率。

相关文章

  • 线程池的原理与C语言实现

    网络数据的处理流程: 1. 检测IO事件是否就绪(可读可写) epoll 等多路复用 2.对IO进行读写 ...

  • 源码分析AsyncTask的工作原理

    一、AsyncTask原理介绍 AsyncTask的实现原理 = 线程池+ Handler 其中:线程池用于线程调...

  • Callable实现原理

    Callable实现原理 Callable的实现类只能配合线程池执行 在线程池中有一个submit方法,可以提交C...

  • 线程以及java线程池实现分享

    线程以及java线程池实现分享 线程简介 JDK线程池的工作原理 JDK线程池的实现细节 1.线程简介-由来 1....

  • 美团一面总结

    线程池的实现原理 参考: Java线程池实现原理及其在美团业务中的实践[https://tech.meituan....

  • 线程池的原理

    参考 深入Java源码理解线程池原理 线程池是对CPU利用的优化手段 线程池使用池化技术实现,替他的实现还有连接池...

  • 一文搞懂Java线程池原理之ThreadPoolExecutor

    在工作中,我们经常使用线程池,但是你真的了解线程池的原理吗?同时,线程池工作原理和底层实现原理也是面试经常问的考题...

  • ThreadPoolExecutor线程池原理

    本文参考Java线程池---addWorker方法解析Java线程池ThreadPoolExecutor实现原理线...

  • 并发编程(三)-线程池与Future

    1. 线程池的实现原理 下图所示为线程池的实现原理:调用方不断地向线程池中提交任务;线程池中有一组线程,不断地从队...

  • MMKV的原理与实现(三)

    MMKV的原理与实现(三) MMKV多线程设计 1. C/C++中的线程:POSIX线程 POSIX,全称为可移植...

网友评论

      本文标题:线程池的原理与C语言实现

      本文链接:https://www.haomeiwen.com/subject/gtlqqrtx.html