C++ 线程池

  1. 线程池的作用:提前申请多个工作线程作为静态的线程资源来应对需要不断并发执行的任务,防止因为频繁的动态线程资源申请和销毁带来的资源消耗

  2. 线程池关键组成:

    1. 一个承载工作任务的任务队列,以及任务队列的添加和取出函数

    2. 互斥锁、条件变量用于控制任务队列的并发访问

    3. 工作线程数组承载提前申请的多个线程资源,以及线程的工作函数

  3. 线程池代码 (游双老师的版本)

#ifndef THREADPOOL_H
#define THREADPOOL_H
#include<exception>
#include<cstdio>
#include<pthread.h>
#include<semaphore.h>
#include<list>
#include<vector>
#include<pthread.h>
using namespace std;
class locker{
public:
    locker(){
        if(pthread_mutex_init(&mutex, NULL) != 0){ // 互斥锁地址,互斥锁属性
            throw exception();
        }
    }
    ~locker(){
        pthread_mutex_destory(&mutex);
    }
    bool lock(){
        return pthread_mutex_lock(&mutex) == 0;
    }
    bool unlock(){
        return pthread_mutex_unlock(&mutex) == 0;
    }
    pthread_mutex_t* get(){
        return &mutex;
    }
    
private:
    pthread_mutex_t mutex;
};

class sem{
public:
    sem(){
        if(sem_init(&m_sem,0,0) != 0){ // sem地址,信号量类型(0为线程,>0则用于进程间通信),初值
            throw exception();
        }
    }
    ~sem(){
        sem_destory(&m_sem);
    }
    bool post(){
        return sem_post(&m_sem) == 0;
    }
    bool wait(){
        return sem_wait(&m_sem) == 0;
    }
private:
    sem_t m_sem;
};

template<class T>
class threadpool{
private:
    int max_threads; //最大线程数
    int max_requests; //最大请求数
    vector<pthread_t> threadArr; // 线程数组
    list<T*>requests_queue; // 请求队列
    locker queue_lock; // 互斥锁
    sem m_sem; // 信号量
    bool is_end; //是否结束线程
    static void* worker(void* arg); // 线程工作函数
    void run(); // 线程工作内容实体,消费者进程
public:
    threadpool(int threads_number = 8, int requests_number = 10000){}; // 初始化线程池
    ~threadpool(){};
    bool append(T* request); // 生产者,将任务添加到队列中
};

template<class T>
threadpool<T>::threadpool(int threads_number, int requests_number):max_threads(threads_number), max_requests(requests_number), is_end(false), threadArr(NULL){
    if(threads_number <= 0 || requests_number <= 0) throw exception(); // 输入异常
    
    threadArr.resize(threads_number); // 创建线程数组
    if(!threadArr) throw exception();
    
    for(int i = 0; i < threads_number; ++i){ // 循环创建线程
        // 指向线程标识符的指针,设置线程属性,线程工作函数,函数参数
        if(pthread_create(threadArr[i], NULL, worker, this) != 0) throw exception();
        if(pthread_detach(threadArr[i])) throw exception(); // 线程独立
    }  
}

template<class T>
threadpool<T>::~threadpool(){
    is_end = true; // 锁资源在类内自动析构
}

template<class T>
bool threadpool<T>::append(T* request){ // 添加队列请求,生产者
    queue_lock.lock(); // 队列加锁
    if(requests_queue.size() >= max_requests) return false; // 超出了最大请求数
    requests_queue.push_back(request);
    queue_lock.unlock(); // 解锁
    m_sem.post(); // 发送信号量唤醒工作线程
    return true;
}

template<class T>
void* threadpool<T>::worker(void* arg){
    threadpool* pool = (threadpool*)arg;
    pool->run();
    return pool;
}

template<class T>
void threadpool<T>::run(){
    while(!is_end){
        m_sem.wait(); // 等待信号量      
        queue_lock.lock(); // 加锁
        if(requests_queue.empty()){
            queue_lock.unlock();
            continue;
        }
        T* request = requests_queue.front(); // 取任务
        requests_queue.pop_front();
        queue_lock.unlock();
        if(!request) continue;
        request->process(); // 执行业务
    }
}
#endif

4.线程池代码(自写C++11版本)

#include<iostream>
#include<vector>
#include<condition_variable>
#include<mutex>
#include<queue>
#include<atomic>
#include<Windows.h>
using namespace std;


class Work {
public:
	Work() {}
	~Work() {}
	void run() {
		cout << "具体工作" << endl;
		Sleep(100);
	}
};

template<class T>
class threadPool {
private:
	mutex mtx;
	condition_variable cond;
	int thread_num;
	atomic<bool> isEnd;
	vector<shared_ptr<thread>>pthreads;
	queue<T*>q;

public:
	threadPool(int _thread_num = 7) :thread_num(_thread_num), isEnd{false} {
		for (int i = 0; i < _thread_num; ++i) {
			pthreads.push_back(
				std::make_shared<thread>(&threadPool::do_task, this)
			);
			cout << "创建线程" << i << endl;
		}
	}

	~threadPool() {
		isEnd.store(true);
		cond.notify_all(); // 唤醒所有线程,执行任务
		for (shared_ptr<thread>& thread : pthreads) {
			if (thread->joinable())
				cout << "线程回收" << endl;
				thread->join(); // 等待线程结束
		}
	}

	void add_task(T* task) {
		unique_lock<mutex>ulock(mtx);
		q.emplace(task);
		cout << "任务数:" << q.size() << endl;
		ulock.unlock();
		cond.notify_all();
	}

	void do_task() {
		while (!isEnd.load()) {
			unique_lock<mutex>ulock(mtx);
			cond.wait(ulock, 
				[this] {
					return this->isEnd.load() || !q.empty();
				});
			if (this->isEnd.load() && q.empty()) return;
			if (q.empty()) continue;
			T* task = q.front();
			q.pop();
			cout << "任务数:" << q.size() << endl;
			ulock.unlock();
			task->run();
		}
	}

};



int main() {
	threadPool<Work>* tp = new threadPool<Work>();
	Work* w = new Work();
	tp->add_task(w);
	tp->add_task(w);
	tp->add_task(w);
	tp->add_task(w);
	tp->add_task(w);
	delete w;
	delete tp;
	Sleep(2000);
	return 0;
}

 作笔记使用,如果错误还请指正,多谢!!!溜了溜了~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

梦想是优秀社畜

您的打赏是对我最大的鼓励!

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

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

打赏作者

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

抵扣说明:

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

余额充值