Programming high-performance server synchronization half / half thread pool reactors template

Semi-synchronous / semi-implemented thread pool reactor model, the work queue for communication using the main thread and the worker threads, the use of the lock (mutexes, semaphores) synchronized operation somewhat similar - Communication "producer consumer" model.

Disadvantages:

1, the use of locks for worker access to the work queue, lock joined reduces the efficiency of the system;

2, must ensure that all client requests are stateless, because it may be handled by different threads with different requests on a connection;

advantage:

1, between the main thread and the worker threads are not coupled relationship, versatility;

2, using the semaphore operating system comes with wake-up mechanism, the worker thread can be achieved basically fair scheduling (worker thread load balancing), the program is simple.

THREADPOOL_H #ifndef 
#define THREADPOOL_H 

#include <List> 
#include <cstdio> 
#include <Exception> 
#include <pthread.h> 
#include "locker.h" // mutex semaphore package, the code slightly 

template <typename T> 
class ThreadPool thread pool // 
{ 
public: 
    ThreadPool (int. 8 = thread_number, int MAX_REQUESTS = 10000); // number of threads in the thread pool thread_number, max_requests to the maximum number of work queue wait 
    ~ threadpool (); 
    bool append (T * request); // add to the work request queue, the need to lock the operation 

Private: 
    static void * worker (void * Arg); // work function threads running continuously removed from the work queue and the task execution , the same operations need to lock 
    void RUN (); 

Private: 
    int m_thread_number; 
    int m_max_requests; 
    pthread_t * m_threads;// thread pool data
    std::list< T* > m_workqueue;//工作队列,FIFO
    locker m_queuelocker;//互斥锁
    sem 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 >::append( T* request )
{
    m_queuelocker.lock();// lock
    IF (m_workqueue.size ()> m_max_requests) 
    { 
        m_queuelocker.unlock (); 
        return to false; 
    } 
    m_workqueue.push_back (Request); 
    m_queuelocker.unlock (); // unlock 
    m_queuestat.post (); // semaphore +1 there are a worker thread wakes 
    return to true; 
} 

Template <typename T> 
void * ThreadPool <T> :: worker (void * Arg) // worker to run the function, described in detail below 
{ 
    ThreadPool the pool * = (* ThreadPool ) Arg; 
    pool-> RUN (); 
    return the pool; 
} 

Template <typename T> 
void ThreadPool <T> :: RUN ()  
{ 
    the while (m_stop!) 
    {
        m_queuestat.wait (); // semaphore -1 
        m_queuelocker.lock (); // add 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

About thread running function:

When using pthread_create function in a C ++ program, the first three parameters must point to a static function, it can not be a member of an object method. So take thread running function is defined as static in the threadpool. Meanwhile, to use a dynamic class members (member variables and member functions) in a static function, the object class can be passed as a parameter to the static function, which calls the method by reference or access the variable. Here passed this pointer when a thread is created pthread_create

Programming high-performance server synchronization half / half thread pool reactors template

Guess you like

Origin www.cnblogs.com/xjyxp/p/11488908.html