最近自己,很煩所以超級久沒學習了,今天趁著抗戰七十周年放三天假,趕緊看下書。
廢話不多說。
今天,介紹乙個簡單的執行緒池。
首先說明什麼是執行緒池,執行緒池:是包含若干個執行緒,來處理多個任務的執行緒集合。
它的目的是用來處理,大量的相對短暫的任務。
這裡我們先來解釋下兩個概念,什麼叫大量呢?對於執行緒來說,需要執行緒數小於任務數,第二,短暫的任務是指,任務需要相對短暫,如果執行緒和主程序同週期,則不適合用執行緒池。
然後來說下cpu數和執行緒數的關係,如果你的任務主要是計算密集型任務
則:執行緒個數 = cpu個數,比較好
如果你的任務是i/o密集型任務
則:執行緒個數》cpu個數,比較好
為什麼計算密集型任務需要執行緒個數 = cpu個數呢?
計算密集型,顧名思義就是應用需要非常多的cpu計算資源,在多核cpu時代,我們要讓每乙個cpu核心都參與計算,將cpu的效能充分利用起來,這樣才算是沒有浪費伺服器配置,如果在非常好的伺服器配置上還執行著單執行緒程式那將是多麼重大的浪費。對於計算密集型的應用,完全是靠cpu的核數來工作,所以為了讓它的優勢完全發揮出來,避免過多的執行緒上下文切換,所以比較理想的安排是執行緒個數 = cpu個數。那麼i/o密集型任務同理。
對於io密集型的應用,就很好理解了,我們現在做的開發大部分都是web應用,涉及到大量的網路傳輸,不僅如此,與資料庫,與快取間的互動也涉及到io,一旦發生io,執行緒就會處於等待狀態,當io結束,資料準備好後,執行緒才會繼續執行。因此從這裡可以發現,對於io密集型的應用,我們可以多設定一些執行緒池中線程的數量(超過cpu數量),這樣就能讓在等待io的這段時間內,執行緒可以去做其它事,提高併發處理效率。當然也不是越多越好。好了說了這麼多,我來貼**了。
condiition.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_h_ */
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 /* _thread_pool_h_ */
threadpool.c
#include
"threadpool.h"
#include
#include
#include
<
string
.h>
#include
#include
void
*thread_routine(void
*arg)
}// 等待到條件,處於工作狀態
pool->idle--;
// 等待到任務
//如果佇列首部不為空,則佇列中有任務
if (pool->first !=
null)
// 如果等待到執行緒池銷毀通知, 且任務都執行完畢
//當隊列為空,並且執行緒的到銷毀通知
if (pool->quit && pool->first ==
null)
if (timeout && pool->first ==
null)
condition_unlock(&pool->ready);
}printf("thread 0x%x is exting\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)
condition_unlock(&pool->ready);
}// 銷毀執行緒池
void threadpool_destroy(threadpool_t *pool)
condition_lock(&pool->ready);
pool->quit =
1; if (pool->counter >
0)
condition_unlock(&pool->ready);
condition_destroy(&pool->ready);
}
main.c
#include "threadpool.h"
#include
#include
#include
void* mytask(void *arg)
int main(void)
//sleep(15);
threadpool_destroy(&pool);
return
0;}
看完**我們繼續看下,執行緒池和我們建立的執行緒有什麼好處呢?
總的來說有兩點
1.當任務增加的時候能夠動態的增加執行緒池中線程的數量直到達到乙個閾值。然後我們再來分析,執行緒池是如何達到這些條件的。2.當任務執行完畢的時候,能夠動態的銷毀執行緒池中的執行緒
首先,我們看在main函式中我們初始化執行緒池,規定了執行緒池中有3個執行緒,然後我們建立了10個任務。
然後在再新增任務的過程中,我們把看是否有等待的程序,如果有就將他喚醒執行任務
如果沒有,那麼建立執行緒。在建立的執行緒中,進行判斷。
如果任務佇列不為空,那麼執行任務。
如果,任務佇列中沒有任務,並且,沒有得到銷毀通知,那麼執行緒陷入等待,如果等待到任務,那麼執行任務,如果在一定時間沒等到,那麼設定超時標誌。
如果,是超時了,並且得到了銷毀通知,那麼當前執行緒數減一,並且將當前執行緒退出。
如果,得到了銷毀通知,並且當前任務佇列中沒有任務,則將當前執行緒數減一,如果當前執行緒數為零,則通知銷毀執行緒函式,並且退出。
而銷毀執行緒函式,執行的是如果銷毀標誌不為零,則返回。如果為零,那麼首先廣播所有的等待的(空閒)執行緒,需要他們退出。如果是正在執行任務的執行緒那麼將收不到他的資訊,將等待執行緒的通知訊號。然後銷毀所有的訊號量。
執行緒池(一) 實現乙個簡單的執行緒池
我們知道頻繁的建立 銷毀執行緒是不可取的,為了減少建立和銷毀執行緒的次數,讓每個執行緒可以多次使用,我們就可以使用執行緒池,可以降低資源到的消耗。執行緒池裡面肯定有多個執行緒,那麼我們就簡單的用乙個陣列來儲存執行緒,那我們我們預設裡面有 5 個執行緒。那我們執行緒池裡只有五個執行緒能同時工作,那同時...
乙個簡單的執行緒池
話說這個執行緒池也寫了好久了 做簡單的東西的時候也在用,最近因為乙個失誤刪掉了自己的一些檔案導致重新寫了一遍 所以貼出來,以防萬一 並且跟大佬們交流 created by cxhmyself on 18 4 10.include 都需要與互斥量一起才能工作 include include inclu...
乙個簡單的執行緒池實現
乙個linux下簡單的執行緒池實現 實現了大部分邏輯,有部分邏輯未實現,只是提供乙個思路 執行緒池類 threadpool.h created on oct 13,2016 author luokun ifndef threadpool h define threadpool h include i...