#include<pthread.h>
#include<unistd.h>
#include<list>
#include<stdio.h>
#include<vector>
#include<list>
static int i = 0;
class Lock{
public:
Lock() {
pthread_mutex_init(&lock_, NULL);
}
~Lock() {
pthread_mutex_unlock(&lock_);
}
void lock() {
pthread_mutex_lock(&lock_);
}
void unlock() {
pthread_mutex_unlock(&lock_);
}
private:
pthread_mutex_t lock_;
};
class Sem{
public:
Sem() {
pthread_cond_init(&cond_, NULL);
}
~Sem() {
pthread_cond_broadcast(&cond_);
}
void wait() {
pthread_cond_wait(&cond_, &lock_);
}
void post() {
pthread_cond_signal(&cond_);
}
private:
pthread_mutex_t lock_;
pthread_cond_t cond_;
};
template <typename T>
class ThreadPool {
public:
ThreadPool(int thd_num = 8, int max_req = 10000);
~ThreadPool();
bool append(T* request);
private:
static void* worker(void* args);
void run();
int max_threads_number_;
int max_requests_number_;
std::vector<pthread_t> threads_;
std::list<T*> works_;
Lock lock_;
Sem sem_;
bool stop_;
};
template <typename T>
ThreadPool<T>::ThreadPool(int thread_number, int max_request):max_threads_number_(thread_number), max_requests_number_(max_request),stop_(false),works_() {
if(thread_number <= 0 || max_request <= 0) {
throw std::exception();
}
//threads_ init
threads_ = std::vector<pthread_t>(max_threads_number_);
for(int i = 0;i<max_threads_number_; ++i)
{
//create pool
if (pthread_create(&threads_[i], NULL, worker, this) != 0) {
throw std::exception();
}
if (pthread_detach(threads_[i])) {
throw std::exception();
}
printf("thread start!%d\n", threads_[i]);
}
}
template<typename T>
ThreadPool<T>::~ThreadPool() {
stop_ = true;
}
template<typename T>
bool ThreadPool<T>::append(T *request) {
lock_.lock();
if (this->works_.size() > max_requests_number_) {
lock_.unlock();
return false;
}
works_.push_back(request);
printf("%d get work\n", getpid());
sem_.post();
lock_.unlock();
return true;
}
template<typename T>
void* ThreadPool<T>::worker(void* arg) {
ThreadPool* self = (ThreadPool*)arg;
self->run();
return self;
}
template<typename T>
void ThreadPool<T>::run() {
while(!stop_)
{
while(works_.empty())sem_.wait();
lock_.lock();
T* request = works_.front();
works_.pop_front();
lock_.unlock();
++i;
}
}
void foo() {
++i;
}
typedef void (*task)();
int main() {
ThreadPool<task> pool(200);
task f = foo;
for(int i = 0;i<10000;i++){printf("add work!\n");pool.append(&f);}
sleep(1);
printf("%d", i);
}
一般都是add work的时候会出现free两次