#include <bits/stdc++.h>
#include <thread>
#include <condition_variable>
#include <list>
#include <mutex>
template <class T>
class threadpool
{
private:
int m_thread_number;
int m_max_requests;
pthread_t *m_threads;
list<T *> m_workqueue;
pthread_mutex_t lock;
pthread_cond_t cond;
bool m_stop;
private:
static void *worker(void *arg);
void run();
public:
threadpool(int thread_number=8, int max_requests=10000)
{
if (thread_number <= 0 || max_requests <= 0)
{
thow std::exception();
}
m_thread_number = thread_number;
m_max_requests = max_requests;
pthread_mutex_init(&lock, NULL);
pthread_cond_init(&cond, NULL);
m_threads = new pthread_t[thread_number];
if (!m_threads)
{
throw std::exception();
}
for (int i = 0; i < thread_number; ++i)
{
if (pthread_create(m_threads + i, NULL, worker, this) != 0)
{
delete[] m_threads;
throw std::exception();
}
if (pthread_detach(m_threads[i]))
{
delete[] m_threads;
throw std::exception();
}
}
}
~threadpool()
{
delete[] m_threads;
m_stop = true;
}
bool append(T *request)
{
if (pthread_mutex_lock(&lock) != 0)
{
return false;
}
if (m_workqueue.size() >= m_max_requests)
{
pthread_cond_unlock(&lock);
return false;
}
m_workqueue.push_back(request);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock);
return true;
}
void *worker(void *arg)
{
threadpool *pool = (threadpool *)arg;
pool->run();
return pool;
}
void run()
{
while (!m_stop)
{
pthread_mutex_lock(&lock);
while (m_workqueue.empty())
{
pthread_cond_wait(&cond, &lock);
}
T *request = m_workqueue.front();
m_workqueue.pop_front();
pthread_mutex_unlock(&lock);
if (!request)
{
continue;
}
request->process();
}
}
};