日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux线程(六)

發(fā)布時間:2024/4/11 linux 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux线程(六) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Linux線程(六)

文章目錄

  • Linux線程(六)
    • 一、線程池

一、線程池

  • 1.線程池:

  • 線程池是一種使用模式。線程過多會帶來調(diào)度開銷,進(jìn)而影響緩存的局部性和整體性能。

  • 而線程池維護(hù)著多個線程,等待監(jiān)督管理者分配可并發(fā)執(zhí)行的任務(wù)。這避免了在處理短時間任務(wù)時創(chuàng)建和銷毀線程的代價。

  • 線程池內(nèi)部不僅能夠保證內(nèi)核的充分利用,還能防止過度調(diào)度。可線程的數(shù)量應(yīng)該取決于可用的并發(fā)處理器、處理器內(nèi)核、內(nèi)存、網(wǎng)絡(luò)socket等的數(shù)量

  • 2.應(yīng)用場景:

  • 需要大量的線程來完成任務(wù),且完成任務(wù)的時間比較短。

  • Web服務(wù)器完成網(wǎng)頁請求這樣的任,非常適合使用線程池來完成。因為單個任務(wù)小,而任務(wù)量巨大。

  • 想象一下熱門網(wǎng)站的點擊次數(shù)和速度。但相對于長時間的任務(wù)。比如一個Telnet鏈接。線程池的優(yōu)點就不明顯了,因為Telnet會話時間比線程創(chuàng)建時間大多了

  • 對性能要求比較苛刻的應(yīng)用。比如服務(wù)器同一時刻要快速響應(yīng)大量客戶的請求

  • 接受突發(fā)性的大量請求,但不至于使服務(wù)器因此產(chǎn)生大量的線程應(yīng)用。突發(fā)性大量客戶請求,在沒有線程池的情況下,將產(chǎn)生大量線程,雖然理論上大部分操作系統(tǒng)線程數(shù)量數(shù)目最大值不是問題,但是短時間內(nèi)產(chǎn)生大量線程可能使內(nèi)存達(dá)到極限出現(xiàn)錯誤

  • 3.線程池種類:

  • 任務(wù)隊列控制的線程池模型,

  • 工作線程控制的線程池模型,

  • 主控線程控制的線程池模型

  • 4.線程池事例:

  • 創(chuàng)建固定數(shù)量的線程池,循環(huán)從任務(wù)隊列中獲取任務(wù)對象

  • 獲取到任務(wù)對象后,執(zhí)行任務(wù)對象的任務(wù)接口

threadpool.hpp

#ifndef __M_POOL_H__ #define __M_POOL_H__ #include <iostream> #include <queue> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <pthread.h> #define MAX_THREAD 3 #define MAX_QUEUE 10class MyTask { private:int data; public:MyTask() {}~MyTask() {}void SetData(int _data){data = _data;}void Run(){int t = rand() % 5;printf("thread:%lu sleep %d sec, execute data:%d\n", pthread_self(), t, data);sleep(t);} };class MyThreadPool { private:int max_thread; //線程池中最大線程數(shù)int cur_thread; //當(dāng)前線程池中的線程數(shù)int keep_running;//用于停止線程池中線程的標(biāo)志int max_queue; //隊列的最大節(jié)點數(shù)pthread_t *tid; //線程的線程IDstd::queue<MyTask *> task_list;pthread_mutex_t mutex;pthread_cond_t empty;pthread_cond_t full;void ThreadLock(){pthread_mutex_lock(&mutex);} void ThreadUnLock(){pthread_mutex_unlock(&mutex);} void ConsumerWait(){pthread_cond_wait(&empty, &mutex);} void ConsumerNotify(){pthread_cond_signal(&empty);}void ProducterWait(){pthread_cond_wait(&full, &mutex);} void ProducterNotify(){pthread_cond_signal(&full);}bool ThreadIsRunning(){return (keep_running == 0 ? false : true);} void ThreadExit(){cur_thread--;//線程池中的線程退出時通知一下主線程printf("thread:%lu exit\n", pthread_self());ProducterNotify();pthread_exit(NULL);} bool QueueIsEmpty(){return (task_list.size() == 0 ? true : false);} bool QueueIsFull(){return (task_list.size() == max_queue ? true : false);}void PopTask(MyTask **task){*task = task_list.front();task_list.pop();return;}void PushTask(MyTask *task){task_list.push(task);}static void *thread_routine(void *arg){MyThreadPool *pthreadpool = (MyThreadPool*)arg;while(1) {pthreadpool->ThreadLock();//若當(dāng)前是運(yùn)行狀態(tài),并且沒有任務(wù)則掛起等待while(pthreadpool->QueueIsEmpty() && pthreadpool->ThreadIsRunning()) {pthreadpool->ConsumerWait();} //若當(dāng)前是非運(yùn)行狀態(tài),且沒有任務(wù)則退出線程//若當(dāng)前時非運(yùn)行狀態(tài),但是隊列中有任務(wù)則需要將任務(wù)執(zhí)行完畢后才能退出if (!pthreadpool->ThreadIsRunning() && pthreadpool->QueueIsEmpty()) {pthreadpool->ThreadUnLock();pthreadpool->ThreadExit();}//能夠走下來,則任務(wù)隊列不為空,那么獲取一個任務(wù)執(zhí)行MyTask *task;pthreadpool->PopTask(&task);pthreadpool->ProducterNotify();pthreadpool->ThreadUnLock();//執(zhí)行任務(wù),不能在鎖內(nèi),否則導(dǎo)致其它線程饑餓task->Run();} return NULL;} public:MyThreadPool(int _max_thread = MAX_THREAD, int _max_queue= MAX_QUEUE):max_thread(_max_thread), max_queue(_max_queue), cur_thread(_max_thread),keep_running(1){int i = 0;printf("create thread:%d-%d\n", max_thread, max_queue);tid = (pthread_t*)malloc(sizeof(pthread_t) * _max_thread);pthread_mutex_init(&mutex, NULL);pthread_cond_init(&full, NULL);pthread_cond_init(&empty, NULL);//創(chuàng)建固定數(shù)量的線程,等待執(zhí)行任務(wù)for(i = 0; i < _max_thread; i++) {int ret = pthread_create(&tid[i], NULL, thread_routine, (void*)this);if (ret != 0) {printf("create thread error\n");exit(0);} pthread_detach(tid[i]);} } ~MyThreadPool(){pthread_mutex_destroy(&mutex);pthread_cond_destroy(&full);pthread_cond_destroy(&empty);}//向線程池任務(wù)隊列中添加任務(wù)bool AddTaskToPool(MyTask *task){ThreadLock();while(QueueIsFull()) {ProducterWait();}PushTask(task);printf("add task to pool\n");ConsumerNotify();ThreadUnLock();return true;}void StopThreadPool(){//若已經(jīng)調(diào)用過線程池退出,則返回if (keep_running == 0) {return;} ThreadLock();keep_running = 0;//如果還有線程沒有退出,則掛起等待//等待所有線程將隊列中的所有任務(wù)都執(zhí)行完畢后并且退出while(cur_thread > 0) {ProducterWait();} ThreadUnLock();} };

threadpool.cpp

#include "threadpool.hpp" int main() {MyTask task[10];int i;MyThreadPool pool;for (i = 0; i < 10; i++) {task[i].SetData(i);pool.AddTaskToPool(&task[i]);}pool.StopThreadPool();return 0; }

總結(jié)

以上是生活随笔為你收集整理的Linux线程(六)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。