thread_pool.h
/*
* thread_pool.h
*
* Created on: May 2, 2014
* Author: root
*/
#ifndef THREAD_POOL_H_
#define THREAD_POOL_H_
#include "thread_locker.h"
#include "thread_sem.h"
#include <list>
#include <cstdio>
#include <exception>
#include <pthread.h>
template<typename T>
class ThreadPool {
public:
ThreadPool( int thread_number = 1, int max_requests = 10000 );
~ThreadPool();
bool Push( T* request ); //推送任务
private:
static void* Worker(void* arg);// 工作线程运行的函数
void Run();
int m_thread_number; //线程池中到线程数
int m_max_requests; //请求队列中允许的最大请求数
pthread_t* m_threads; //描述线程池到数组,其大小为m_thread_number
std::list< T* > m_workqueue; //队列
ThreadLocker m_queuelocker; /*保护请求队列的互斥锁*/
ThreadSem m_queuestat; /*是否有任务需要处理*/
bool m_stop; /*是否结束线程*/
};
template< typename T >
ThreadPool< T >::ThreadPool( int thread_number, int max_requests ) :
m_thread_number( thread_number ),
m_max_requests( max_requests ),
m_stop( false ),
m_threads( NULL )
{
if( ( thread_number <= 0 ) || ( max_requests <= 0 ) )
{
throw std::exception();
}
m_threads = new pthread_t[ m_thread_number ];
if( ! m_threads )
{
throw std::exception();
}
for ( int i = 0; i < thread_number; ++i )
{
printf( "create the %dth thread\n", 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();
}
}
}
template< typename T >
ThreadPool< T >::~ThreadPool()
{
delete [] m_threads;
m_stop = true;
}
template< typename T >
bool ThreadPool< T >::Push( T* request )
{
m_queuelocker.Lock(); // 工作队列加锁
if ( m_workqueue.size() > m_max_requests )
{
m_queuelocker.Unlock();
return false;
}
m_workqueue.push_back( request );
m_queuelocker.Unlock();
m_queuestat.Post();
return true;
}
template< typename T >
void* ThreadPool< T >::Worker( void* arg )
{
ThreadPool* pool = ( ThreadPool* )arg;
pool->Run();
return pool;
}
template< typename T >
void ThreadPool< T >::Run()
{
while ( ! m_stop )
{
m_queuestat.Wait();
m_queuelocker.Lock();
if ( m_workqueue.empty() )
{
m_queuelocker.Unlock();
continue;
}
T* request = m_workqueue.front(); //返回链表第一个元素的引用
m_workqueue.pop_front();// 删除链表头到一个元素
m_queuelocker.Unlock();
if ( ! request )
{
continue;
}
request->process();
}
}
#endif /* THREAD_POOL_H_ */
thread_locker.h
/*
* thread_locker.h
*
* Created on: May 2, 2014
* Author: root
*/
#ifndef LOCKER_H_
#define LOCKER_H_
#include <exception>
#include <pthread.h>
class ThreadLocker {
public:
ThreadLocker()
{
if(pthread_mutex_init(&m_mutex,NULL) != 0)
{
throw std::exception();
}
}
~ThreadLocker()
{
pthread_mutex_destroy(&m_mutex);
}
//加锁
bool Lock()
{
return pthread_mutex_lock(&m_mutex) == 0;
}
//解锁
bool Unlock()
{
return pthread_mutex_unlock(&m_mutex) == 0;
}
private:
pthread_mutex_t m_mutex;
};
#endif
thread_cond.h
/*
* thread_cond.h
*
* Created on: May 3, 2014
* Author: root
*/
#ifndef COND_H_
#define COND_H_
#include <pthread.h>
#include <exception>
class ThreadCond
{
public:
ThreadCond()
{
if( pthread_mutex_init( &m_mutex, NULL ) != 0)
{
throw std::exception();
}
if( pthread_cond_init( &m_cond, NULL) != 0)
{
//释放资源
pthread_mutex_destroy( &m_mutex);
throw std::exception();
}
}
//销毁条件变量
~ThreadCond()
{
pthread_mutex_destroy( &m_mutex );
pthread_cond_destroy( &m_cond);
}
//等待条件变量
bool Wait()
{
int ret = 0;
pthread_mutex_lock( &m_mutex);
ret = pthread_cond_wait( &m_cond, &m_mutex );
pthread_mutex_unlock( &m_mutex );
return ret == 0;
}
//唤醒等待条件变量的线程
bool Signal()
{
return pthread_cond_signal( &m_cond ) == 0;
}
private:
pthread_mutex_t m_mutex;
pthread_cond_t m_cond;
};
#endif /* COND_H_ */
thread_sems.h
/*
* thread_sems.h
*
* Created on: May 2, 2014
* Author: root
*/
#ifndef SEMS_H_
#define SEMS_H_
#include <semaphore.h>
#include <exception>
class ThreadSem
{
public:
ThreadSem()
{
if( sem_init( &m_sem, 0, 0 ) != 0 )
{
throw std::exception();
}
}
//销毁信号量
~ThreadSem()
{
sem_destroy( &m_sem );
}
//等待信号量
bool Wait()
{
return sem_wait( &m_sem ) == 0;
}
//增加信号量
bool Post()
{
return sem_post( &m_sem ) == 0;
}
private:
sem_t m_sem;
};
#endif /* SEMS_H_ */
file_test.h
/*
* file_test.h
*
* Created on: May 2, 2014
* Author: root
*/
#ifndef FILE_TEST_H_
#define FILE_TEST_H_
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>
class FileTest {
public:
FileTest();
virtual ~FileTest();
void process();
void setFileName(std::string filename);
static void test();
private:
std::string m_filename;
//bool status;
};
#endif /* FILE_TEST_H_ */
/*
* file_test.cpp
*
* Created on: May 2, 2014
* Author: root
*/
#include "file_test.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <cstdio>
#include <iostream>
#include <fstream>
#include <sstream>
#include "log/log.h"
#include<fstream>
using namespace std;
static int num = 0;
FileTest::FileTest():m_filename("") {
// TODO Auto-generated constructor stub
}
FileTest::~FileTest() {
// TODO Auto-generated destructor stub
}
void FileTest::setFileName(std::string filename)
{
m_filename = filename;
}
std::string IntToString(int i){
string c;
ostringstream oss;
oss<<i;
c=oss.str();
return c;
}
static Logs logger=Logs::instance();
void FileTest::process()
{
num++;
logger.write_error("num:");
logger.write_error(IntToString(num).c_str());
logger.write_error(m_filename.c_str());
}
void FileTest::test()
{
num++;
cout << num << endl;
}
main.c
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sstream>
#include "file_test.h"
#include "thread/thread_pool.h"
using namespace std;
static std::string IntToString(int i){
string c;
ostringstream oss;
oss<<i;
c=oss.str();
return c;
}
int main()
{
ThreadPool<FileTest>* thread = new ThreadPool<FileTest>(5,1024);
FileTest* file_test = new FileTest[5];
for(int i = 0; i < 5; ++i){
std::string filename("filename");
filename.append(IntToString(i));
filename.append(".txt");
(file_test + i)->setFileName(filename);
thread->Push(file_test + i);
}
while(false)
{
for(int i = 0; i < 24; ++i)
{
(file_test + i)->test();
}
}
sleep(5);
delete []file_test;
delete thread;
return 0;
}