什麼是執行緒池?簡單點說,執行緒池就是有一堆已經建立好了的執行緒,初始它們都處於空閒等待狀態,當有新的任務需要處理的時候,就從這個池子裡面取乙個空閒等待的執行緒來處理該任務,當處理完成了就再次把該執行緒放回池中,以供後面的任務使用。當池子裡的執行緒全都處理忙碌狀態時,執行緒池中沒有可用的空閒等待執行緒,此時,根據需要選擇建立乙個新的執行緒並置入池中,或者通知任務執行緒池忙,稍後再試。
我們說,執行緒的建立和銷毀比之程序的建立和銷毀是輕量級的,但是當我們的任務需要大量進行大量執行緒的建立和銷毀操作時,這個消耗就會變成的相當大。比如,當你設計乙個壓力效能測試框架的時候,需要連續產生大量的併發操作,這個是時候,執行緒池就可以很好的幫上你的忙。執行緒池的好處就在於執行緒復用,乙個任務處理完成後,當前執行緒可以直接處理下乙個任務,而不是銷毀後再建立,非常適用於連續產生大量併發任務的場合。
執行緒池的任務就在於負責這些執行緒的建立,銷毀和任務處理引數傳遞、喚醒和等待。
1. 建立若干執行緒,置入執行緒池
2. 任務達到時,從執行緒池取空閒執行緒
3. 取得了空閒執行緒,立即進行任務處理
4. 否則新建乙個執行緒,並置入執行緒池,執行3
5. 如果建立失敗或者執行緒池已滿,根據設計策略選擇返回錯誤或將任務置入處理佇列,等待處理
6. 銷毀執行緒池
#ifndef _thread_pool_h_
#define _thread_pool_h_
#include #include #include #include #include #include #include #include #define max_waiting_tasks 1000 //最大等待數
#define max_active_threads 20 //最大執行執行緒數
struct task //單向鍊錶的任務節點
;typedef struct thread_pool//執行緒池結構體
thread_pool;
bool
init_pool(thread_pool *pool,
unsigned int threads_number); //初始化池
bool
add_task(thread_pool *pool,//新增任務
void *(*task)(void *arg),
void *arg);
int
add_thread(thread_pool *pool,//增加執行緒
unsigned int additional_threads_number);
int
remove_thread(thread_pool *pool, //去除執行緒
unsigned int removing_threads_number);
bool destroy_pool(thread_pool *pool); //銷毀執行緒池
void *routine(void *arg);
#endif
#include "thread_pool.h"
void handler(void *arg) //預防 執行緒在執行過程中 被remove掉而導致的死鎖
pthread_mutex_unlock((pthread_mutex_t *)arg); 解鎖
}void *routine(void *arg)//執行緒的任務
if(pool->waiting_tasks == 0 && pool->shutdown == true) //如果任務為空,任務全部完成,則推出執行緒
p = pool->task_list->next;//把節點插入單向鍊錶
pool->task_list->next = p->next;
pool->waiting_tasks--;
pthread_mutex_unlock(&pool->lock);//解鎖pthread_cleanup_pop(0); //解除預防死鎖功能
pthread_setcancelstate(pthread_cancel_disable, null);//進入不接受 任何刪除執行緒的模式
(p->task)(p->arg);//執行任務
pthread_setcancelstate(pthread_cancel_enable, null);//回到可接受模式
free(p);//釋放節點
} pthread_exit(null);//退出執行緒
}bool init_pool(thread_pool *pool, unsigned int threads_number) //初始化執行緒池
pool->task_list->next = null;
pool->waiting_tasks = 0;
pool->active_threads = threads_number;
int i;
for(i=0; iactive_threads; i++) }
return true;}
bool add_task(thread_pool *pool,void *(*task)(void *arg), void *arg)
new_task->task = task;
new_task->arg = arg;
new_task->next = null;
pthread_mutex_lock(&pool->lock);
if(pool->waiting_tasks >= max_waiting_tasks)
struct task *tmp = pool->task_list;
while(tmp->next != null)
tmp = tmp->next;
tmp->next = new_task;
pool->waiting_tasks++;
pthread_mutex_unlock(&pool->lock);
pthread_cond_signal(&pool->cond);
return true;
}int add_thread(thread_pool *pool, unsigned additional_threads)
actual_increment++;
}pool->active_threads += actual_increment;
return actual_increment;
} int remove_thread(thread_pool *pool, unsigned int removing_threads)
if(i == pool->active_threads-1)
return -1;
else
} bool destroy_pool(thread_pool *pool)
else
printf("[%u] is joined\n", (unsigned)pool->tids[i]);
} free(pool->task_list);
free(pool->tids);
free(pool);
return true;
}main.c
#include "thread_pool.h"
void *mytask(void *arg)
void *count_time(void *arg)
}int main(void)
fedora30建立嵌入式linux開發環境
閒來無事研究了一下最新的fedora30如何作嵌入式開發,和老版本略有不同,記錄一下 1.首先是交叉編譯器安裝,這個沒什麼好說的,就是解壓後新增環境變數,網上都能找到,需要注意的一點是使 用64位系統的話還需要安裝32位的glibc庫,否則執行arm linux gcc v 會報 no such f...
嵌入式工程實訓第8天
專案名稱 嵌入式工程實訓 第八天 今日進度以及任務 嵌入式linux c程式設計 檔案程式設計 嵌入式linux 多執行緒程式設計 任務完成情況 動手實現了檔案api的相關操作,對檔案程式設計有了更深入的理解,對linux檔案描述符的分配和多工程式設計也有了一定的認識。開發 現的問題彙總 多工程式設...
嵌入式開發第16天(開發板觸控驅動,mmap)
lcd lcd驅動檔案或者它的路徑 dev fb0 測試是否是lcd驅動檔案 cat smarthome jpg dir 10.jpg dev fb0 觸控庫安裝 1 將觸控庫放在ubuntu與windows共享目錄中 2 sudo s 密碼 123456 3 cp mnt hgfs linuxsh...