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