线程安全--线程池,了解线程池什么样,单例模式-三种方式实现单例模式,构造函数私有化(懒汉饿汉)。懒汉方式,饿汉方式,STL智能指针的安全性,

本文介绍了线程池的概念、优点和应用场景,强调了其在处理大量任务时的效率和资源管理优势。接着讨论了线程的单例模式,包括饿汉和懒汉两种实现方式及其优缺点。最后提到了STL容器和智能指针的线程安全性问题,指出在多线程环境中使用时需要注意手动加锁保护。
摘要由CSDN通过智能技术生成

**

线程池

**
线程池是什么?
线程池是线程安全的更加具体的应用。
线程池主要还是一种任务处理的思路,对于大量的任务或者数据进行处理的场景。
对于大量的请求任务,单个线程是无法承载的,所以我们需要多个执行流。

第一种想法:
来一个任务,创建一个线程,处理任务,然后销毁线程。
缺点:
1、在大量峰值下,需要创建大量的线程,消耗大量的资源,系统崩溃
2、创建线程时间T1,处理任务T2,销毁线程T3,如果T1+T2时间过多,不合理。
针对上边想法的改进,我们提出了线程池这个东西。
有一个或者多个线程 对任务进行处理的实体叫做线程池。(线程处理任务是靠入口函数)
线程池包括什么?
有数量上限的线程+线程安全的任务队列
1、线程池中线程是提前创建好的,因为有上限,所以资源不会消耗。
2、线程不断的从任务队列中取出任务进行处理。
优点
1、避免了大量创建线程和销毁线程带来的时间成本。
2、避免了当大量请求任务来了之后,短时间创建大量线程导致系统崩溃。
3、线程池不仅能够保证内核的充分利用,还能防止过分调度(没有了cpu的调度)。可用线程数量应该取决于可用的并发处理器、处理器内核、内存网络sockets等的数量。
一般的线程的入口函数
都是在创建线程的时候,就固定传入的什么函数名。void的函数参数*。,会导致线程池中的线程任务处理的方式过于单一。
但是线程池中的线程
我们在任务队列中不仅传入数据,还传入数据处理的方法。所以线程池中的线程只需要传入的方法,处理的数据就好了,但是不管是什么方法,什么数据,如何处理。
在这里插入图片描述

线程的应用场景:
1、需要大量的线程来完成任务,并且任务处理的时间短。例如web服务器完成网页的请求这样的任务。
2、对性能要求苛刻的应用。例如服务器迅速响应客户。
3、能够接受突发性的大量任务请求。虽然操作系统线程数组最大值没有问题,但是短时间产生大量线程可能使内存达到极限,系统崩溃。

线程池的实现
//实现了消费者线程(就是线程池中提前生成的线程)   的生产者消费者模型
//先定义一个池子
#define MAX_THREAD 5//定义一个宏,表示线程池中的最大线程个数
class ThreadPool
{
   
 private:
   int thr_max;//定义线程池中线程的最大数量,初始化时创建相应数量的线程即可。
   std::queue<MyTask>   _queue;//放任务的队列,对于任务队列里边的任务,它有数据还有处理方式,所以这个任务应该是自定义的。
   ~~~~int capacity~~ ;~~ //这个容量是不需要的,在第一个消费者生产者模型里边queue需要大小,防止内存被耗尽,但是线程池里边是不需要capacity的,因为任务总会被线程处理掉,,老师第二遍讲的时候queue给大小了,并且建立了cond_cus和cond_pro,其实都差不多
   pthread_mutex_t mutex;//线程池一定要是安全的,所以要有锁子
   pthread_cond_t cond;//线程池中的消费者需要同步进行,需要一个条件。而且只需要消费者的同步,生产者是在外部的,不影响的
  public:
     ThreadPool(int max = MAX_THREAD)//缺省参数
       :thr_max(max)
     {
   
        pthread_mutex_init(&mutex,NULL);
        pthread_cond_inint(&cond,NULL);
        ///因为消费者的线程是出现在线程池中的,所以消费者者的线程在线程池的创建中,也应该创建出来
        for(int i = 0; i < thr_max;i++)
        {
   
           pthread_t tid;
           int ret = pthread_create(&tid,NULL,thr_start,this);//传递的这个this看下边的thr_start那里
           if(ret != 0)
           {
   
             printf("线程创建失败了");
             exit(0);
           }
        }
     }
     ~ThreadPool()
     {
   
        pthread_mutex_destory(&mutex,NULL);
        pthread_cond_destory(&cond,NULL);
     }
     //外部的生产者生产任务,将数据与处理方式放到任务队列中,外部的生产者函数入口应该在线程池的外部,跟前边的消费者生产者模型是一样的。但是消费者的线程入口函数应该在线程池内部,因为消费者线程本身就应该在线程池内部
     bool PushTask(ThreadTask& task)
     {
   
        //生产者要访问queue,所以加锁
        pthread_mutex_lock(&mutex);
        ///如果这里queue有大小,要注意入队判断queue是不是满了,满了需要阻塞使用pthread_cond_wait(&cond_pro,&mutex)//这里如果queue有大小了,那就必须得来一个cond_pro的条件队列。因为队列满了,需要生产者进行等待的,这时候用一个cond等待队列就会有问题。
        queue.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值