1.用於執行大量相對短暫的任務執行緒池擁有若干個執行緒,通常情況下都小於併發的任務量,所以任務需要進入佇列進行等待。2.當任務增加的時候能夠動態的增加執行緒池中線程的數量值到達乙個閾值
3.當任務執行完畢的時候,能夠動態的銷毀執行緒池中的執行緒
4.該執行緒池的實現本質上也是生產者與消費者模型的應用。生產者執行緒向任務佇列新增任務,一旦佇列有任務到來,如果有等待 執行緒就喚醒來執行任務,如果沒有等待執行緒並且執行緒數沒有達到閾值,就建立執行緒來執行任務。
1、執行緒是稀缺資源,使用執行緒池可以減少建立和銷毀執行緒的次數,每個工作執行緒都可以重複使用。
2、可以根據系統的承受能力,調整執行緒池中工作執行緒的數量,防止因為消耗過多記憶體導致伺服器崩潰。
計算密集型任務,占用cpu較長時間,很少被打斷,此時執行緒池中線程的個數=cpu個數最佳,如果執行緒個數超過cpu個數,而cpu個數是一定的,這意味著能夠併發的數目是一定的,這是就是少量的cpu排程較多的執行緒,涉及到執行緒間的切換開銷,因為會降低效率
i/o密集型任務,當執行任務的時候,可能會被i/o中斷,也就是執行緒會被掛起,這種情況執行緒個數》cpu個數是合理的,假設cpu個數為2,分配的執行緒個數也為2,此時兩個執行緒都可以執行i/o任務,但是有這種情況是兩個執行緒都阻塞在i/o,這時讓出了cpu的控制權,此時如果又來了任務,但是執行緒個數只有2個,而都處於阻塞,也就沒有辦法執行,因而對於i/o密集型任務,執行緒個數要大於cpu個數
condition.h
#ifndef _condition_h_
#define _condition_h_
#include //封裝乙個互斥量和條件變數作為狀態
typedef struct condition
condition_t;
//對狀態的操作函式
//初始化乙個條件變數
int condition_init(condition_t *cond);
//對互斥鎖鎖定
int condition_lock(condition_t *cond);
//對互斥鎖解鎖
int condition_unlock(condition_t *cond);
//在條件變數之上等待條件
int condition_wait(condition_t *cond);
//具有超時的等待功能
int condition_timedwait(condition_t *cond, const struct timespec *abstime);
//向等待執行緒發起通知
int condition_signal(condition_t* cond);
//向等待廣播
int condition_broadcast(condition_t *cond);
//銷毀條件變數
int condition_destroy(condition_t *cond);
#endif
condition.c
#include "condition.h"
//初始化
int condition_init(condition_t *cond)
//加鎖
int condition_lock(condition_t *cond)
//解鎖
int condition_unlock(condition_t *cond)
//等待
int condition_wait(condition_t *cond)
//固定時間等待
int condition_timedwait(condition_t *cond, const struct timespec *abstime)
//喚醒乙個睡眠執行緒
int condition_signal(condition_t* cond)
//喚醒所有睡眠執行緒
int condition_broadcast(condition_t *cond)
//銷毀
int condition_destroy(condition_t *cond)
threadpool.h
#ifndef _thread_pool_h_
#define _thread_pool_h_
//執行緒池標頭檔案
#include "condition.h"
//任務結構體,將任務放入佇列由執行緒池中的執行緒來執行
typedef struct task
task_t;
//下面是執行緒池結構體
typedef struct threadpool
threadpool_t;
//執行緒池初始化
void threadpool_init(threadpool_t *pool, int threads);
//往執行緒池中加入任務
void threadpool_add_task(threadpool_t *pool, void *(*run)(void *arg), void *arg);
//摧毀執行緒池
void threadpool_destroy(threadpool_t *pool);
#endif
threadpool.c
#include "threadpool.h"
#include #include #include #include #include //建立的執行緒執行
void *thread_routine(void *arg)
}//等待到條件,處於工作狀態
pool->idle--;
//等待到了任務
if(pool->first != null)
//等待到執行緒池銷毀通知(通過在threadpool_destroy函式中設定 pool->quit = 1;),且任務執行完畢
if(pool->quit && pool->first == null)
condition_unlock(&pool->ready);
break;
}//超時,跳出銷毀執行緒
if(timeout == 1)
condition_unlock(&pool->ready);
}printf("thread %d is exiting\n", (int)pthread_self());
return null;
}//執行緒池初始化
void threadpool_init(threadpool_t *pool, int threads)
//增加乙個任務到執行緒池
void threadpool_add_task(threadpool_t *pool, void *(*run)(void *arg), void *arg)
else
pool->last = newtask; //佇列尾指向新加入的執行緒
//執行緒池中有執行緒空閒,喚醒
if(pool->idle > 0)
//當前執行緒池中線程個數沒有達到設定的最大值,建立乙個新的線性
else if(pool->counter < pool->max_threads)
//結束,訪問
condition_unlock(&pool->ready);
}//執行緒池銷毀
//等待執行緒將所有任務執行完畢之後在銷毀
void threadpool_destroy(threadpool_t *pool)
//加鎖
condition_lock(&pool->ready);
//設定銷毀標記為1
pool->quit = 1;
//執行緒池中當前執行緒個數大於0
if(pool->counter > 0)
//處於執行任務狀態中的執行緒,不會收到廣播
//執行緒池中需要等待執行任務狀態中的執行緒全部退出
while(pool->counter)
}condition_unlock(&pool->ready);
condition_destroy(&pool->ready);
}
main.c
#include "threadpool.h"
#include #include #include void* mytask(void *arg)
//測試**
int main(void)
threadpool_destroy(&pool);
return 0;
}
makefile
.phony:clean
cc=gcc
cflags=-wall -g
all=main
all:$(all)
objs=threadpool.o main.o condition.o
.o.c:
$(cc) $(cflags) -c $<
main:$(objs)
$(cc) $(cflags) $^ -o $@ -lpthread -lrt
clean:
rm -f $(all) *.o
簡單執行緒池實現
執行緒池可以處理多執行緒問題,只要將任務放到任務佇列中,執行緒池中的執行緒就會從佇列中取任務,以預設的優先順序開始執行,如果你的任務數大於正在工作的執行緒數,則執行緒池將會建立一根新的執行緒來輔助工作,但是永遠都不會超過執行緒池中線程的最大值。執行緒池的結構 pragma once include ...
簡單執行緒池實現
1.用於執行大量相對短暫的任務 2.當任務增加的時候能夠動態的增加執行緒池中線程的數量值到達乙個閾值 3.當任務執行完畢的時候,能夠動態的銷毀執行緒池中的執行緒 4.該執行緒池的實現本質上也是生產者與消費者模型的應用。生產者執行緒向任務佇列新增任務,一旦佇列有任務到來,如果有等待執行緒就喚醒來執行任...
自實現簡單執行緒池
執行緒池在現在的系統和框架中十分常見。明白執行緒池的思想原理,不僅對學習執行緒池有 很大的幫助。對理解一些系統的執行緒池實現也有很大的幫助。下面是我自己簡單實現的一 個執行緒池。用以對執行緒的簡單理解。執行緒的實現原理很簡單 執行緒池物件包含以下元件 工作者佇列,job佇列 使用者通過執行緒池物件新...