linux通用线程池设计I

来源:互联网 发布:linux 删除海量小文件 编辑:程序博客网 时间:2024/06/06 09:56

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 -WallTARGET := libthreadpool.soSRCS := $(wildcard *.cpp)OBJS := $(patsubst %cpp,%o,$(SRCS))LIB=-lpthreadINCLUDE=-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)

0 0