線程池的創建

當我們需要追求性能時候,一個進程的 創建銷燬時間也許不算什麼,但是當進程需要調用大量進程時候,但是每一個線程運行時間在創建銷燬這個線程當中所佔比例並不是百分之百,換句話說線程的創建銷燬時間是不可以忽略的
那麼類似與懶漢模式當我們需要創建大量線程時候,就提前創建一組線程然後我們用的時候直接在這個線程組裏面拿這樣不是牛逼很多了嘛!
我們通過一個隊列是線程有一個先來後到的順序,然後在隊列中取之運行你要運行的某一個進程函數。

  • 還是看代碼吧,不知道說什麼了~~~
#include <iostream>
#include <queue>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>

#define MAX_THREAD  5
#define MAX_QUEUE   10

class Task
{
    private:
        void *_data;
    public:
        void SetData(void *data)
        {
            _data = data;
        }
        bool Run()
        {
            srand(time(NULL));
            int n = rand() % 5;
            //任務所要執行的操作
            printf("thread:%p--run:%s--sleep:%d\n", 
                    pthread_self(), _data, n);
            sleep(n);
            return true;
        }
};
class ThreadPool
{
    private:
        int _max_thread;
        int _cur_thread;
        bool _stop_flags;//線程池中線程的退出標誌 1-退出
        int _cap;
        std::queue<Task *> _tlist;
        pthread_mutex_t _lock;
        pthread_cond_t  _empty;
        pthread_cond_t  _full;
        void ThreadLock()
        {
            pthread_mutex_lock(&_lock);
        }
        void ThreadUnLock()
        {
            pthread_mutex_unlock(&_lock);
        }
        //任務隊列爲空則等待
        void ConsumerWait()
        {
            pthread_cond_wait(&_empty, &_lock);
        }
        void ConsumerNotice()
        {
            pthread_cond_signal(&_empty);
        }
        void ConsumerNoticeAll()
        {
            pthread_cond_broadcast(&_empty);
        }
        //任務隊列滿了要等待
        void ProductorWait()
        {
            pthread_cond_wait(&_full, &_lock);
        }
        void ProductorNotice()
        {
            pthread_cond_signal(&_full);
        }
        bool QueueIsEmpty()
        {
            return _tlist.empty();
        }
        bool QueueIsFull()
        {
            return (_tlist.size() == _cap);
        }
        bool ThreadIsStop()
        {
            return _stop_flags;
        }
        void ThreadExit()
        {
            _cur_thread--;
            ThreadUnLock();
            ProductorNotice();
            pthread_exit(NULL);
        }
        bool QueuePopData(Task **task)
        {
            *task = _tlist.front();
            _tlist.pop();
            return true;
        }
        static void *thr_start(void *arg)
        {
            ThreadPool *pool = (ThreadPool*)arg;
            while(1) {
                printf("into thr_start\n");
                pool->ThreadLock();
                while(pool->QueueIsEmpty() && !pool->ThreadIsStop()) {
                    pool->ProductorNotice();
                    pool->ConsumerWait();
                }
                if (pool->QueueIsEmpty() && pool->ThreadIsStop()) {
                    printf("task queue is empty\n");
                    pool->ThreadExit();
                }
                printf("get data\n");
                Task *task;
                pool->QueuePopData(&task);
                pool->ThreadUnLock();
                task->Run();
            }
            return NULL;
        }
    public:
        ThreadPool(int max_thread = MAX_THREAD, 
                int max_queue = MAX_QUEUE):_max_thread(max_thread),
        _cur_thread(max_thread),_cap(max_queue), 
        _stop_flags(false) {
            pthread_mutex_init(&_lock, NULL);        
            pthread_cond_init(&_full, NULL);        
            pthread_cond_init(&_empty, NULL);        
        }
        ~ThreadPool()
        {
            pthread_mutex_destroy(&_lock);
            pthread_cond_destroy(&_full);
            pthread_cond_destroy(&_empty);
        }
        bool Start()
        {
            int i = 0;
            int ret = -1;
            pthread_t tid;
            for (i = 0; i < _max_thread; i++) {
                ret = pthread_create(&tid, NULL, thr_start, (void*)this);
                if (ret != 0) {
                    printf("create thread error\n");
                    return false;
                }
                pthread_detach(tid);
            }
            return true;
        }
        bool Stop()
        {
            ThreadLock();
            if (_stop_flags == true) {
                ThreadUnLock();
                return false;
            }
            _stop_flags = true;
            while(_cur_thread > 0) {
                ConsumerNoticeAll();
                ProductorWait();
            }
            ThreadUnLock();
            return true;
        }
        bool AddTask(Task *task) 
        {
            ThreadLock();
            while(QueueIsFull()) {
                ConsumerNotice();
                ProductorWait();
            }
            printf("add data~~\n");
            _tlist.push(task);
            ThreadUnLock();
            ConsumerNotice();
            return true;
        }
};

int main()
{
    ThreadPool t;
    t.Start();
    int i = 0;
    Task task[10];

    for (i = 0; i < 10; i++) {
        printf("add data\n");
        task[i].SetData((void*)"SingHwnag2019!!");
        t.AddTask(&task[i]);
    }
    t.Stop();
    return 0;
}

代碼上總體來說了 線程池 = 多個線程 + 任務隊列

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章