Linux上開發時爲了提高程序的運行效率,經常需要使用的多線程,但是在Linux並沒有看到一套發行的線程池,至少筆者沒有看到。有人會說,用boost就搞定了呀。筆者沒有看過boost源碼,但是感覺過於龐大了,綜上,設計自己使用的線程池還是有實際意義和必要的。
posix線程常用api
pthread_create
pthread_join
pthread_detach
pthread_kill
pthread_cancle
….
線程池設計
線程池需要維護一個任務隊列m_tsk,可以給tsk設計priority,線程優先從任務隊列中取得優先級高的任務。
用戶自定義任務的執行的函數指針,這樣,線程池就可以適用於多種不同的任務了。
源代碼
ThreadMng.h
#ifndef THREADMNG_H_
#define THREADMNG_H_
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <pthread.h>
#include <semaphore.h>
#include <vector>
#include <stdio.h>
#include <stdarg.h>
typedef std::vector<void*> TaskContainer;
namespace std_thread_pool
{
#define echo(format , ...) \
fprintf(stdout ,"[%s,%s,%d]"format"\n" ,__FILE__,__func__,__LINE__, ##__VA_ARGS__) ;\
fflush(stdout) ;
enum
{
e_thread_init = 0 ,
e_thread_suspend,
e_thread_working ,
e_thread_idle
};
typedef struct __thread_info__
{
pthread_t id ;
int index;
int status ;
void* pthis ;
}__attribute__((packed)) thread_info ,*p_thread_info;
typedef struct __thread_param__
{
int (*action)( void*) ;
void* param ;
int id ;
int priority ;
}__attribute__((packed)) thread_param ,*p_thread_param;
class Lock
{
public:
Lock() ;
~Lock() ;
public:
static pthread_mutex_t mutex ;
};
class threadpool
{
public:
threadpool() ;
~threadpool() ;
public:
const long start() ;
const long end() ;
static void *ThreadMain( void *p) ;
void put(void *p) ;
int get( void **p) ;
void reset() ;
private:
static bool bEnd ;
sem_t m_sem_job_wait;
TaskContainer m_tsk ;
p_thread_info m_pThreadInfo ;
} ;
} ;
#endif
ThreadMng.cpp
#include "ThreadMng.h"
#include <sys/fcntl.h>
#include <stdio.h>
#include <string.h>
#include <error.h>
#include <errno.h>
#include <signal.h>
using namespace std_thread_pool ;
pthread_mutex_t Lock::mutex = PTHREAD_MUTEX_INITIALIZER ;
Lock::Lock()
{
pthread_mutex_lock( &mutex) ;
}
Lock::~Lock()
{
pthread_mutex_unlock( &mutex ) ;
}
bool threadpool::bEnd = false;
threadpool::threadpool()
{
sem_init( &m_sem_job_wait , 0 , 0 ) ;
m_tsk.clear() ;
m_pThreadInfo = new thread_info[4] ;
}
threadpool::~threadpool()
{
sem_destroy( &m_sem_job_wait) ;
delete [] m_pThreadInfo ;
}
const long threadpool::start()
{
for( int i = 0 ; i < 4 ; i++)
{
m_pThreadInfo[i].index = i ;
m_pThreadInfo[i].status=e_thread_init ;
m_pThreadInfo[i].pthis = this ;
pthread_create(&m_pThreadInfo[i].id , NULL , threadpool::ThreadMain ,\
(void*)&m_pThreadInfo[i] ) ;
}
return 0 ;
}
const long threadpool::end()
{
{
Lock oLock ;
bEnd = true ;
}
for( int i = 0 ; i < 4 ; i++)
{
if( pthread_kill( m_pThreadInfo[i].id , 0 ) == 0 )
{
pthread_join(m_pThreadInfo[i].id , NULL );
}
}
return 0;
}
void *threadpool::ThreadMain( void *p)
{
if( !p )
{
pthread_exit( 0 ) ;
}
p_thread_info pthread = (p_thread_info) p ;
pthread->status = e_thread_suspend ;
void *tsk =NULL;
threadpool *pthis = (threadpool*)pthread->pthis ;
while( !bEnd && !pthis->get( &tsk) )
{
pthread->status = e_thread_working ;
p_thread_param pParam = (p_thread_param)tsk ;
(*pParam->action)(pParam->param) ;
pthread->status = e_thread_idle ;
}
return NULL;
}
void threadpool::put(void *p)
{
{
Lock oLock ;
m_tsk.push_back( p ) ;
}
sem_post(&m_sem_job_wait) ;
}
int threadpool::get(void **p)
{
sem_wait(&m_sem_job_wait) ;
{
Lock oLock ;
if(m_tsk.size() )
{
TaskContainer::iterator it_tsk = m_tsk.begin() ;
*p = *it_tsk ;
m_tsk.erase( it_tsk ) ;
}
return 0;
}
return -1;
}
MakeFile
CC := g++
CFLAGS := -g -Wall
TARGET := libthreadpool.so
SRCS := $(wildcard *.cpp)
OBJS := $(patsubst %cpp,%o,$(SRCS))
LIB=-lpthread
INCLUDE=-I./
all:$(TARGET)
$(OBJS):$(SRCS)
$(CC) -c $< -g $(LIB) $(INCLUDE)
$(TARGET):$(OBJS)
#ar -rc $@ $^
$(CC) -shared -fPIC -o $@ $^
clean:
rm -rf $(TARGET) *.o
線程池啓動之後,處於hangup狀態,任務來到時線程纔會轉入到working狀態。
多線程編程時,內存的持久化是一個永恆的命題。用戶自定義的thread_param對象必須是持久化得對象.(new alloc malloc)