實現一個線程池

來源:互聯網
上載者:User
一.線程最主要的三個同步機制

1.訊號量

2.互斥鎖

3.條件變數

二.對三個同步機制分別實現一個封裝類

#ifdef LOCKER_H#define LOCKER_H#include #include /*訊號量的封裝*/class sem{public:    sem()    {        if( sem_init( &sem_like, 0, 0))        {            throw std::exception();        }    }    ~sem()    {        sem_destroy( &sem_like);    }    bool wait()    {        return sem_wait( &sem_like)== 0;    }    bool post()    {        return sem_post( &sem_like)== 0;    }private:    sem_t sem_like;}/*互斥鎖的封裝*/class locker{public:    locker()    {        if( pthread_mutex_init( &mutex_like,NULL) !=0)        {            throw std::exception();        }    }    ~locker()    {        pthread_mutex_destroy( &mutex_like);    }    bool lock()    {        return pthread_mutex_lock( &mutex_like)== 0;    }    bool unlock()    {        return pthread_mutex_unlock( &mutex_like);    }private:    pthread_mutex_t mutex_like;}/*條件變數的封裝*/class cond{public:    cond()    {        if( pthread_mutex_init( &mutex_like,NULL)!= 0)        {            throw std::exception;        }        if( pthread_cond_init( &cond_like, NULL)!= 0)        {            //釋放對應的互斥鎖            pthread_mutex_destroy( &mutex_like);            throw std::exception;        }    }    ~cond()    {        pthread_mutex_destroy( &mutex_like);        pthread_cond_destroy( &cond_like);    }    bool wait()    {        int flag= 0;        pthread_mutex_lock( &mutex_like);        flag= pthread_cond_wait( &cond_like, &mutex_like);        pthread_mutex_unlock( &mutex_like);        return flag== 0;    }    bool signal()    {        return pthread_cond_signal( &cond_like)== 0;    }private:    pthread_mutex_t mutex_like;    pthread_cond_t cond_like;}#endif

三.實現線程池

動態建立線程十分消耗時間,如果有一個線程池,使用者請求到來時,從線程池取一個閒置線程來處理使用者的請求,請求處理完後,線程又變為空白閑狀態,等待下次被使用。


核心資料結構有兩個:線程容器 、請求隊列

1.線程容器

這裡用一個vector容器來存放線程池裡面所有線程的id

2.請求隊列

這裡用list容器來存放所有請求,請求處理按fifo的順序

#ifndef THREADPOOL_H#define THREADPOOL_H#include #include #include #include #include "locker.h"template< typename T >class threadpool{public:    threadpool( int thread_number = 8, int max_requests = 10000 );    ~threadpool();    bool append( T* request );private:    static void* worker( void* arg );    void run();private:    int thread_number_like;//當前線程池中的線程個數    int max_requests_like;//最大請求數    //pthread_t* threads_like;    vector< pthread> threads_like;//線程容器    std::list< T* > workqueue_like;//請求隊列    locker queuelocker_like;//請求隊列的訪問互斥鎖    sem queuestat_like;//用於請求隊列與空閑線程同步的訊號量    bool stop_like;//結束所有線程,線程池此時沒有線程};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();    }      threads_like.resize( thread_number_like);    if( thread_number_like!=  threads_like.size() )    {        throw std::exception();    }    for ( int i = 0; i < thread_number_like; ++i )    {        printf( "create the %dth thread\n", i );        if( pthread_create( &threads_like [i], NULL, worker, this ) != 0 )//建立線程        {            threads_like.resize(0);            throw std::exception();        }        if( pthread_detach( m_threads[i] ) )//設定為脫離線程        {            threads_like.resize(0);            throw std::exception();        }    }}template< typename T >threadpool< T >::~threadpool(){    stop_like = true;}template< typename T >bool threadpool< T >::append( T* request ){    queuelocker_like.lock();    if ( workqueue_like.size() > max_requests_like )    {        queuelocker_like.unlock();        return false;    }    workqueue_like.push_back( request );    queuelocker_like.unlock();    queuestat_like.post();    return true;}template< typename T >void* threadpool< T >::worker( void* arg ){    threadpool* pool = ( threadpool* )arg;//靜態函數要調用動態成員run,必須通過參數arg得到    pool->run();//線程的執行體    return pool;}template< typename T >void threadpool< T >::run(){    while ( ! m_stop )    {        queuestat_like.wait();        queuelocker_like.lock();        if ( workqueue_like.empty() )        {            queuelocker_like.unlock();            continue;        }        T* request = workqueue_like.front();        workqueue_like.pop_front();        queuelocker_like.unlock();        if ( ! request )        {            continue;        }        request->process();//執行當前請求所對應的處理函數    }}#endif

註:1.這裡的線程池模型中,每一個線程對應一個請求

2.這種方式保證了使用者請求的及時處理,對請求的處理函數效能要求更小,因為這種模型並不要求請求處理過程是非堵塞的,因為一個請求的處理時延不會影響到系統對其他請求的處理(當然線程數必須能動態增加)。

3.這種方式對於高並發伺服器並不是最優的,類似於nginx的一個進程對應多個使用者請求的方式更有優勢,nginx模型的優勢主要有兩個:一:進程數固定,不會因為同時有很多線程或者進程而佔用過多的記憶體。二:nginx的背景工作處理序數一般與cpu的核心數一致,並可以把一個進程綁定到一個核上,這樣就節省了進程切換或線程切換帶來的系統開銷


以上就介紹了實現一個線程池,包括了方面的內容,希望對PHP教程有興趣的朋友有所協助。

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.