c++11最简单的线程池实现

c++学习 专栏收录该内容
17 篇文章 0 订阅

线程池是在处理高并发任务中有比较重要的价值,他的实现最基本原理就生产者和消费者模型,刚开始就开一定数量的线程,以程序中的某些功能模块为对象,以生产者与消费者模型为基本原理,不断使用这些固定数量的线程调度进行处理,避免了在高并发情况下,不断开辟线程造成的进程资源消耗.下面是一个简单的线程池程序,主要使用C++11中一些简单的新特性的最简单的线程池实现.
ThreadPool.h

#pragma once

#include <iostream>
#include<stdlib.h>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<vector>
#include<functional>
#include<queue>
#define N 10
using namespace std;
class ThreadPool{

public:
    //自定义void()的函数类型
    typedef function<void()>Task;

    ThreadPool();
    ~ThreadPool();
    
public:
    size_t initnum;
    //线程数组
    vector<thread>threads ;
    
    //任务队列
    queue<Task>task ;
    
    //互斥锁条件变量
    mutex _mutex ;
    condition_variable cond ;
    
    //线程池工作结束时为真
    bool done ;
    
    //队列是否为空
    bool isEmpty ;
    //队列是否为满
    bool isFull;

public:
    void addTask(const Task&f);
    void start(int num);
    void setSize(int num);
    void runTask();
    void finish();
};

ThreadPool.cpp

#include"ThreadPool.h"
ThreadPool ::ThreadPool():done(false),isEmpty(true),isFull(false){
}

//设置池中初始线程数
void ThreadPool::setSize(int num){
        (*this).initnum = num ;
}

//添加任务
void ThreadPool::addTask(const Task&f){
   
    if(!done){
        //保护共享资源    
        unique_lock<mutex>lk(_mutex);
        
        //要是任务数量到了最大,就等待处理完再添加
        while(isFull){
            cond.wait(lk);
        }

        //给队列中添加任务
        task.push(f);
        
        if(task.size()==initnum)
            isFull = true;
        
        cout<<"Add a task"<<endl;
        isEmpty = false ;
        cond.notify_one();
    }
}

void ThreadPool::finish(){
    
        //线程池结束工作
        for(size_t i =0 ;i<threads.size();i++){
               threads[i].join() ;
        }
}

void ThreadPool::runTask(){
    
    //不断遍历队列,判断要是有任务的话,就执行
    while(!done){

        unique_lock<mutex>lk(_mutex);
        
        //队列为空的话,就等待任务
        while(isEmpty){
            cond.wait(lk);
        }
        
        Task ta ;
        //转移控制快,将左值引用转换为右值引用
        ta = move(task.front());  
        task.pop();
        
        if(task.empty()){
            isEmpty = true ;    
        }    
        
        isFull =false ;
        ta();
        cond.notify_one();
    }
}

void ThreadPool::start(int num){
    
    setSize(num);
    
    for(int i=0;i<num;i++){        
        threads.push_back(thread(&ThreadPool::runTask,this));
    }
}
ThreadPool::~ThreadPool(){   
}

Test.cpp

#include <iostream>
#include"ThreadPool.h"
void func(int i){
    cout<<"task finish"<<"------>"<<i<<endl;
}
int main()
{

    ThreadPool p ;
    p.start(N);
    int i=0;

    while(1){
        i++;
        //调整线程之间cpu调度,可以去掉
       this_thread::sleep_for(chrono::seconds(1));
        auto task = bind(func,i);
        p.addTask(task);
    }

    p.finish();
    return 0;
}

简单的makefile

CC = g++
CXXFLAGS=-lpthread -g
target:Test.cpp ThreadPool.o
	$(CC) Test.cpp ThreadPool.o -o Test $(CXXFLAGS)
ThreadPool.o:ThreadPool.cpp
	$(CC) -c ThreadPool.cpp $(CXXFLAGS)
clean:
	rm *.o

运行截图
在这里插入图片描述

  • 4
    点赞
  • 10
    评论
  • 61
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值