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

线程池实现

发布时间:2022-12-16 14:41:50 所属栏目:Linux 来源:未知
导读: 线程池
1. 线程池概念
线程池:一种线程使用模式,线程过多会带来调度开销,进而影响缓存局部性和整体性能. 而线程池维护着多个线程线程池linux,等待着管理者分配可并发执行的任务. 这避免

线程池

1. 线程池概念

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

线程池的应用场景:

需要大量的线程来完成任务,且任务完成的时间比较短,Web服务器完成网页请求这样的任务,使用线程池技术是非常合适的,因为单个任务小,而任务数量巨大,你可以想象一个热门网站的点击次数,但对于长时间的任务,线程池的任务就不明显了.对性能要求苛刻的应用,比如要求服务器迅速响应客户请求.接受突发性的大量请求,但不至于使服务器因此产生大量线程的应用,突发性大量客户请求,在没有线程池情况下,将产生大量线程,虽然理论上大多数操作系统线程数目最大值不是问题,短时间内产生大量线程可能使内存到达极限,出现错误.

线程池的示例:

创建固定数量线程池,循环从任务队列中获取任务对象.获取到任务对象后,执行任务对象中的任务接口. 2. 线程池实现

#pragma once
#include
#include
#include
#include
#include
#include "Log.hpp"
using namespace std;
int gThreadNum = 5;
template<class T>
class ThreadPool
{
public:
    ThreadPool(int threadNum = gThreadNum)
        : threadNum_(gThreadNum)
        , isStart_(false)
    {
        assert(threadNum_ > 0);
        pthread_mutex_init(&mutex_, nullptr);
        pthread_cond_init(&cond_, nullptr);
    }
    ~ThreadPool()
    {
        pthread_mutex_destroy(&mutex_);
        pthread_cond_destroy(&cond_);
    }
    static void* threadRoutine(void* args)
    {
        pthread_detach(pthread_self());
        ThreadPool<T>* tp = static_cast<ThreadPool<T>* >(args);
        prctl(PR_SET_NAME, "follower");
        while(1)
        {
            tp->lockQueue();
            //如果没任务就wait
            while(!tp->haveTask())
            {
                tp->waitForTask();
            }
            //这个任务被一个线程执行
            T t = tp->pop();
            tp->unlockQueue();
            int one, two;
            char oper;
            t.get(&one, &two, &oper);
            Log()<<"新线程完成计算任务: "<< one << oper << two << "=" << t.run() << "\n";
        }
    }
    //调用start, 线程池开始工作
    void start()
    {
        assert(!isStart_);
        for(int i = 0; i < threadNum_; ++i)
        {
            pthread_t temp;
            pthread_create(&temp, nullptr, threadRoutine, this);
        }
        isStart_ = true;
    }
    void push(const T& in)
    {
        lockQueue();
        taskQueue_.push(in);
        choiceThreadForHandler();
        unlockQueue();
    }
private:
    void lockQueue() { pthread_mutex_lock(&mutex_); }
    void unlockQueue() { pthread_mutex_unlock(&mutex_); }
    bool haveTask() { return !taskQueue_.empty(); }  //有无任务
    void waitForTask() { pthread_cond_wait(&cond_, &mutex_); }
    void choiceThreadForHandler() { pthread_cond_signal(&cond_); } //选择一个线程去处理
    T pop()
    {
        T temp = taskQueue_.front();
        taskQueue_.pop();
        return temp;
    }
private:
    bool isStart_;
    int threadNum_;
    queue<T> taskQueue_;  //任务队列
    pthread_mutex_t mutex_;  //互斥锁
    pthread_cond_t cond_;
};

//测试线程池
#include "ThreadPool.hpp"
#include "Task.hpp"
#include "Log.hpp"
#include 
#include 
#include 
int main()
{
    prctl(PR_SET_NAME, "master");
    const string operators = "+-*/";
    ThreadPool<Task>* tp = new ThreadPool<Task>();
    tp->start();
    srand((unsigned long)time(nullptr) ^ getpid() ^ pthread_self());
    //派发任务
    while(true)
    {
        int one = rand() % 50;
        int two = rand() % 10;
        char oper = operators[rand() % operators.size()];
        Log() << "主线程派发计算任务" << one << oper << two << "=?" << "\n";
        Task t(one, two, oper);
        tp->push(t);
        sleep(1);
    }
    return 0;
}

image-20221127002353528

(编辑:海南站长网)

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