網路程式設計 簡單執行緒池的原理和實現

2021-07-04 13:07:15 字數 2437 閱讀 7018

一. 什麼是執行緒池?:

諸如web伺服器、資料庫伺服器、檔案伺服器和郵件伺服器等許多伺服器應用都面向處理來自某些遠端**的大量短小的任務。構建伺服器應用程式的乙個過於簡單的模型是:每當乙個請求到達就建立乙個新的服務物件,然後在新的服務物件中為請求服務。但當有大量請求併發訪問時,伺服器不斷的建立和銷毀物件的開銷很大。所以提高伺服器效率的乙個手段就是盡可能減少建立和銷毀物件的次數,特別是一些很耗資源的物件建立和銷毀,這樣就引入了「池」的概念,「池」的概念使得人們可以定製一定量的資源,然後對這些資源進行復用,而不是頻繁的建立和銷毀。

執行緒池是預先建立執行緒的一種技術。執行緒池在還沒有任務到來之前,建立一定數量的執行緒,放入空閒佇列中。這些執行緒都是處於睡眠狀態,即均為啟動,不消耗cpu,而只是占用較小的記憶體空間。當請求到來之後,緩衝池給這次請求分配乙個空閒執行緒,把請求傳入此執行緒中執行,進行處理。當預先建立的執行緒都處於執行狀態,即預製執行緒不夠,執行緒池可以自由建立一定數量的新執行緒,用於處理更多的請求。當系統比較閒的時候,也可以通過移除一部分一直處於停用狀態的執行緒。

二. 執行緒池的注意事項

(1)執行緒池大小。多執行緒應用並非執行緒越多越好,需要根據系統執行的軟硬體環境以及應用本身的特點決定執行緒池的大小。一般來說,如果**結構合理的話,執行緒數目與cpu 數量相適合即可。如果執行緒執行時可能出現阻塞現象,可相應增加池的大小;如有必要可採用自適應演算法來動態調整執行緒池的大小,以提高cpu 的有效利用率和系統的整體效能。

(2)併發錯誤。多執行緒應用要特別注意併發錯誤,要從邏輯上保證程式的正確性,注意避免死鎖現象的發生。

(3)執行緒洩漏。這是執行緒池應用中乙個嚴重的問題,當任務執行完畢而執行緒沒能返回池中就會發生執行緒洩漏現象。

三. 執行緒池的設計

(1)threadpool_init()函式: 完成執行緒池的初始化工作,包括初始化任務佇列、初始化條件變數和互斥鎖、初始化執行緒、並給執行緒註冊thread_worker()函式

(2)threadpool_add()函式: 向任務佇列中新增任務,包括執行緒實際執行的函式指標和所需的引數,並將任務佇列長度加一。

(3)threadpool_worker()函式: 實際工作函式,該函式是乙個while迴圈,進入迴圈後先判斷任務佇列長度,如果任務佇列長度為零,則阻塞在pthread_cond_wait呼叫,如果接收到訊號或者進入函式時佇列長度不為零,則從任務佇列中取出乙個任務,佇列長度減一,然後執行任務。

(4)threadpool_destroy()函式: 銷毀執行緒池,等待子執行緒結束後,銷毀各種資源。

#include

#include

struct threadpool_task;

struct threadpool_t;

threadpool_t *threadpool_init(int threadnum); //初始化

int threadpool_add(threadpool_t *pt, void (*func)(void*), void *arg); //生產者

int threadpool_destroy(threadpool_t *pt);

int threadpool_gettasksize(threadpool_t* pool);

#include "threadpool.h"

using namespace std;

static

void *threadpool_worker(void *arg);

threadpool_t *threadpool_init(int threadnum)

//生產者建立乙個任務並新增到任務佇列中

int threadpool_add(threadpool_t *pool, void (*func)(void *), void *arg)

//消費者處理執行緒

static

void *threadpool_worker(void *arg)

task = pool->head->next;

if(task == null) continue;

pool->head->next = task->next;

pool->queue_size--;

pthread_mutex_unlock(&(pool->lock));

task->func(task->arg);

free(task);

}pthread_mutex_unlock(&(pool->lock));

pthread_exit(null);

return

null;

}int threadpool_destroy(threadpool_t* pool)

int threadpool_gettasksize(threadpool_t* pool)

簡單執行緒池實現

執行緒池可以處理多執行緒問題,只要將任務放到任務佇列中,執行緒池中的執行緒就會從佇列中取任務,以預設的優先順序開始執行,如果你的任務數大於正在工作的執行緒數,則執行緒池將會建立一根新的執行緒來輔助工作,但是永遠都不會超過執行緒池中線程的最大值。執行緒池的結構 pragma once include ...

簡單執行緒池實現

1.用於執行大量相對短暫的任務 2.當任務增加的時候能夠動態的增加執行緒池中線程的數量值到達乙個閾值 3.當任務執行完畢的時候,能夠動態的銷毀執行緒池中的執行緒 4.該執行緒池的實現本質上也是生產者與消費者模型的應用。生產者執行緒向任務佇列新增任務,一旦佇列有任務到來,如果有等待 執行緒就喚醒來執行...

簡單執行緒池實現

1.用於執行大量相對短暫的任務 2.當任務增加的時候能夠動態的增加執行緒池中線程的數量值到達乙個閾值 3.當任務執行完畢的時候,能夠動態的銷毀執行緒池中的執行緒 4.該執行緒池的實現本質上也是生產者與消費者模型的應用。生產者執行緒向任務佇列新增任務,一旦佇列有任務到來,如果有等待執行緒就喚醒來執行任...