(一)条件变量版本
threadpool.cpp
#include<iostream>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<queue>
class Start{
public:
Start(int id)
:id_(id)
{}
virtual void Run(){
printf("Start is running!!!\n");
}
int id_;
};
class ThreadPool{
public:
ThreadPool(int threadSize)
:threadSize_(threadSize)
,threadCurNum_(0)
{
pthread_mutex_init(&mutex_,NULL);
pthread_cond_init(&cond_,NULL);
isQuit_=false;
pthread_t tid;
for(int i=0;i<threadSize;++i){
pthread_create(&tid,NULL,threadStart,this);
++threadCurNum_;
}
}
~ThreadPool(){
pthread_mutex_destroy(&mutex_);
pthread_cond_destroy(&cond_);
}
void push(Start* data){
pthread_mutex_lock(&mutex_);
if(isQuit_){
pthread_mutex_unlock(&mutex_); //释放线程就不允许再增加数据了
return;
}
que_.push(data);
pthread_mutex_unlock(&mutex_);
pthread_cond_signal(&cond_);
}
void pop(Start** data){
pthread_mutex_lock(&mutex_);
while(0==que_.size()){
if(isQuit_){ //释放线程池
--threadCurNum_;
pthread_mutex_unlock(&mutex_);
pthread_exit(NULL); //线程退出
}
pthread_cond_wait(&cond_,&mutex_);
}
*data=que_.front();
que_.pop();
pthread_mutex_unlock(&mutex_);
}
void threadClear(){
pthread_mutex_lock(&mutex_);
isQuit_=true; //标记要释放线程池里的线程
pthread_mutex_unlock(&mutex_);
if(threadCurNum_>0)
pthread_cond_broadcast(&cond_); //唤醒所有线程去争抢锁资源
}
private:
static void *threadStart(void *arg){
ThreadPool *ptr=(ThreadPool*)arg;
while(1){
Start *p=nullptr;
ptr->pop(&p);
p->Run();
delete[] p;
}
}
int threadSize_;
std::queue<Start*> que_;
bool isQuit_;
int threadCurNum_;
pthread_mutex_t mutex_;
pthread_cond_t cond_;
};
main.cpp
#include "threadpool.cpp"
using namespace std;
#define ThreadSize 10
#define MyStartCount 100
class MyStart:public Start{
public:
MyStart(int id)
:Start(id)
{}
void Run()override{
cout<<"id= "<<id_<<",thread="<<pthread_self()<<endl;
usleep(300);
}
};
int main(){
ThreadPool pool(ThreadSize);
for(int i=0;i<MyStartCount;++i){
MyStart *p=new MyStart(i);
pool.push(p);
}
//while(1)
sleep(6);
pool.threadClear();
return 0;
}
(二)POSIX信号量版本
blockingqueue.hpp
#pragma once
#include<iostream>
#include<semaphore.h>
#include<vector>
using namespace std;
template<class T>
class BlockingQueue
{
public:
BlockingQueue(int maxsize=100)//默认阻塞队列大小为100
:_queue(maxsize)
,_head(0)
,_tail(0)
,_size(0)
,_maxsize(maxsize)
{
sem_init(&_lock,0,1);
sem_init(&_used,0,0);
sem_init(&_rem,0,maxsize);
}
~BlockingQueue()
{
sem_destroy(&_lock);
sem_destroy(&_used);
sem_destroy(&_rem);
}
void Push(const T& data)
{
sem_wait(&_rem);
sem_wait(&_lock);
_queue[_tail]=data;
_tail=(_tail+1)%_maxsize;
++_size;
sem_post(&_lock);
sem_post(&_used);
}
void Pop(T& data)
{
sem_wait(&_used);
sem_wait(&_lock);
data=_queue[_head];
_head=(_head+1)%_maxsize;
--_size;
sem_post(&_lock);
sem_post(&_rem);
}
private:
int _head;
int _tail;
int _size;
int _maxsize;
vector<T> _queue;
sem_t _lock;//互斥锁
sem_t _used;//已使用
sem_t _rem;//未使用
};
threadpool.hpp
#pragma once
#include"blockingqueue.hpp"
class Stack
{
public:
virtual void Run()
{
cout<<"Stack-----\n";
}
virtual ~Stack()
{}
};
//线程池
class ThreadPool
{
public:
ThreadPool(int thread_size,int queue_size=100)//默认阻塞队列大小为100
:_queue(queue_size)
,_size(thread_size)
{
for(int i=0;i<_size;++i)
{
pthread_t tid;
pthread_create(&tid,NULL,PthreadEntry,this);//调用函数必须为静态且需要传入this指针
tid_arr.push_back(tid);
}
}
~ThreadPool()
{
for(int i=0;i<_size;++i)
{
pthread_cancel(tid_arr[i]);
}
for(int i=0;i<_size;++i)
{
pthread_join(tid_arr[i],NULL);
}
}
void AddStack(Stack* ptr)//用父类指针接收,多态的特性
{
_queue.Push(ptr);
}
private:
BlockingQueue<Stack*> _queue;//阻塞队列里存放线程执行代码的父类指针,使用多态调用
int _size;//线程个数
vector<pthread_t> tid_arr;//线程tid数组
static void* PthreadEntry(void* arg)
{
ThreadPool* ptr=(ThreadPool*)arg;//接收this指针
while(1)
{
Stack* pst=NULL;
ptr->_queue.Pop(pst);//从阻塞队列中取执行代码
pst->Run();//多态
delete pst;
}
}
};
main.cc
#include"threadpool.hpp"
#include<sys/syscall.h>
#include<unistd.h>
#include<stdio.h>
class MyStack:public Stack{
public:
MyStack(int n)
:_id(n)
{}
void Run()override//重写父类的函数,改为自己需要执行的代码
{
printf("MyStack---tid=%d,id=%d\n",syscall(SYS_gettid),_id);
}
~MyStack()override//重写析构函数,释放子类的资源
{}
private:
int _id;
};
int main()
{
ThreadPool pool(10);//创建10个进程
for(int i=0;i<20;++i)
{
pool.AddStack(new MyStack(i));
}
while(1)
sleep(1);
return 0;
}