【Linux】线程——线程池、线程池的实现、线程安全的线程池、单例模式的概念、饿汉和懒汉模式、互斥锁、条件变量、信号量、自旋锁、读写锁

Linux线程

7. 线程池

  线程池是一种多线程编程中的技术和概念。

  它是一种线程使用模式。是一组预先创建好的线程集合,这些线程处于等待状态,随时准备接受任务并执行。

在这里插入图片描述

  

7.1 线程池介绍

为什么使用线程池

  线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量。

  

线程池的应用场景

  (1)需要大量的线程来完成任务,且完成任务的时间比较短。 WEB服务器完成网页请求这样的任务,使用线程池技术是非常合适的。因为单个任务小,而任务数量巨大,你可以想象一个热门网站的点击次数。 但对于长时间的任务,比如一个Telnet连接请求,线程池的优点就不明显了。因为Telnet会话时间比线程的创建时间大多了。

  (2)对性能要求苛刻的应用,比如要求服务器迅速响应客户请求。

  (3)接受突发性的大量请求,但不至于使服务器因此产生大量线程的应用。 突发性大量客户请求,在没有线程池情况下,将产生大量线程,虽然理论上大部分操作系统线程数目最大值不是问题,短时间内产生大量线程可能使内存到达极限,出现错误。

  

使用线程池的优点

  (1)提高性能:避免了频繁创建和销毁线程的开销,因为线程的创建和销毁是比较耗时的操作。

  (2)控制资源:可以限制线程的数量,防止过多的线程竞争系统资源,导致系统性能下降甚至崩溃。

  (3)提高响应性:能够更快地响应新的任务请求,因为线程已经准备好,无需等待线程创建。

  

7.2 线程池的实现

线程池示例

  (1)创建固定数量线程池,循环从任务队列中获取任务对象。

  (2)获取到任务对象后,执行任务对象中的任务接口。

  

执行任务:

#pragma once
#include <iostream>
#include <string>

std::string opers="+-*/%";

enum{
   
    DivZero=1,
    ModZero,
    Unknown
};

class Task
{
   
public:
    Task()
    {
   }
    
    Task(int x,int y,char op)
        :_data1(x),_data2(y),_oper(op),_result(0),_exitcode(0)
    {
   }

    void run()
    {
   
        switch (_oper)
        {
   
        case '+':
            _result=_data1+_data2;
            break;
        case '-':
            _result=_data1-_data2;
            break;
        case '*':
            _result=_data1*_data2;
            break;
        case '/':
            {
   
                if(_data2==0) _exitcode=DivZero;
                else _result=_data1/_data2;
            }
            break;
        case '%':
            {
   
                if(_data2==0) _exitcode=ModZero;
                else _result=_data1%_data2;
            }
            break;
        default:
            _exitcode=Unknown;
            break;
        }
    }

    //Task对象重载运算符(),()直接进行run函数
    void operator()()
    {
   
        run();
    }

    std::string GetResult()
    {
   
        std::string r=std::to_string(_data1);
        r+=_oper;
        r+=std::to_string(_data2);
        r+="=";
        r+=std::to_string(_result);
        r+="[code: ";
        r+=std::to_string(_exitcode);
        r+="]";

        return r;
    }

    std::string GetTask()
    {
   
        std::string r=std::to_string(_data1);
        r+=_oper;
        r+=std::to_string(_data2);
        r+="=?";
        return r;
    }

    ~Task()
    {
   }

private: 
    int _data1;
    int _data2;
    char _oper;

    int _result;
    int _exitcode;
};

  

线程池:

#pragma once

#include <iostream>
#include <vector>
#include <queue>
#include <string>
#include <pthread.h>
#include <unistd.h>
#include "Task.hpp"

struct ThreadData
{
   
    pthread_t tid;
    std::string name;
};

static const int defaultnum=5; //默认线程数量

//实现我们的线程池
template<class T>
class ThreadPool
{
   
public:
    void Lock()
    {
   
        pthread_mutex_lock(&_mutex);
    }

    void Unlock()
    {
   
        pthread_mutex_unlock(&_mutex);
    }

    void Wakeup()
    {
   
        pthread_cond_signal(&_cond);
    }

    void ThreadSleep()
    {
   
        pthread_cond_wait(&_cond
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鳄鱼麻薯球

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值