自学内容网 自学内容网

【线程】线程池

池化技术,弄一个池,预先弄好资源,当有比如任务来的时候,就交给这个池,就可以很快的处理任务

线程池是创建出一堆线程,类似于池,创建出线程池,提前创建出一批线程,当有任务的时候,就可以直接交给线程池处理,这样可以很好的提高效率

下面利用原生线程库来实现线程池

大家可以拷贝到VS Code下来看

代码中的一个解释

main.cc

#include<iostream>
#include<unistd.h>
#include<time.h>
#include"threadpool.hpp"

using namespace std;

int main()
{
    srand(time(nullptr) ^ getpid());

    ThreadPool<Task>* tp=new ThreadPool<Task>;
    tp->Start();
    while(true)
    {
        //1. 构建任务
        int x = rand() % 10 + 1;
        usleep(10);
        int y = rand() % 5;
        char op = opers[rand()%opers.size()];

        Task t(x, y, op);
        tp->Push(t);
        //2. 交给线程池处理
        std::cout << "main thread make task: " << t.GetTask() << std::endl;

        sleep(1);
    }
    return 0;
}

threadpool.hpp

#pragma once
#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <pthread.h>
#include "task.hpp"

using namespace std;

struct ThreadInfo
{
    pthread_t tid;
    string name;
};

template <class T>
class ThreadPool
{
public:
    void Lock()
    {
        pthread_mutex_lock(&mutex_);
    }
    void Unlock()
    {
        pthread_mutex_unlock(&mutex_);
    }
    void Threadsleep()
    {
        pthread_cond_wait(&cond_, &mutex_);
    }
    void Wakeup()
    {
        pthread_cond_signal(&cond_);
    }
    bool IsQueueEmpty()
    {
        return tasks_.empty();
    }

    string GetThreadName(pthread_t tid)
    {
        for (const auto &ti : threads_)
        {
            if (ti.tid == tid)
                return ti.name;
        }
        return "None";
    }

public:
    ThreadPool(int num = 5) : threads_(num)
    {
        pthread_mutex_init(&mutex_, nullptr);
        pthread_cond_init(&cond_, nullptr);
    }
    static void *HandlerTask(void *args) // 必须定义为静态函数,这样才不会传this指针过来,才不会导致函数不匹配问题
    {
        ThreadPool<T> *tp = static_cast<ThreadPool<T> *>(args);
        string name=tp->GetThreadName(pthread_self());
        while(true)
        {
            tp->Lock();
            while(tp->IsQueueEmpty())
            {
                tp->Threadsleep();
            }
            //消费任务
            T t=tp->Pop();
            tp->Unlock();
            //处理任务
            t();
            cout <<name << " run, "<< "result: " << t.GetResult() <<endl;

        }
        return nullptr;
    }
    
    void Start()
    {
        int size = threads_.size();
        for (int i = 0; i < size; i++)
        {
            threads_[i].name= "thread-" + to_string(i + 1);
            pthread_create(&(threads_[i].tid), nullptr, HandlerTask, this); // 传入this指针,使静态函数可以访问类内成员和函数
        }
    }
    T Pop()
    {
        T out=tasks_.front();
        tasks_.pop();
        return out;
    }
    void Push(const T& in)
    {
        //需要加锁
        Lock();
        tasks_.push(in);
        Wakeup();
        Unlock();
    }
    ~ThreadPool()
    {
        pthread_mutex_destroy(&mutex_);
        pthread_cond_destroy(&cond_);
    }

private:
    vector<ThreadInfo> threads_; // 用数组管理创建出来的线程
    queue<T> tasks_;             // 用队列来管理任务

    pthread_mutex_t mutex_;
    pthread_cond_t cond_;
};

Task.hpp

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

using namespace std;
string opers="+-*/%";

enum
{
    Divzero = 1,
    Modzero,
    Unknown
};

class Task
{
public:
    Task()
    {}
    Task(int data1, int data2, char op) : _data1(data1), _data2(data2), _op(op), _result(0), _exitcode(0)
    {}
    void run()
    {
        switch (_op)
        {
        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;
        }
        }
    }
    void operator()()
    {
        run();
    }
    string GetResult()
    {
        string r=to_string(_data1);
        r+=_op;
        r+=to_string(_data2);
        r+='=';
        r+=to_string(_result);
        r+='[';
        r+=to_string(_exitcode);
        r+=']';
        return r;
    }
    string GetTask()
    {
        string r=to_string(_data1);
        r+=_op;
        r+=to_string(_data2);
        r+="=?";
        return r;
    }

private:
    int _data1;
    int _data2;
    char _op;
    int _result;
    int _exitcode;
};

 

 


原文地址:https://blog.csdn.net/2302_81250321/article/details/142525555

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!