linux通用线程池设计I

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fallinlovelj/article/details/43637755

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)

猜你喜欢

转载自blog.csdn.net/fallinlovelj/article/details/43637755