嵌入式開發第30天(執行緒池)

2021-07-16 22:23:24 字數 3755 閱讀 8403

什麼是執行緒池?簡單點說,執行緒池就是有一堆已經建立好了的執行緒,初始它們都處於空閒等待狀態,當有新的任務需要處理的時候,就從這個池子裡面取乙個空閒等待的執行緒來處理該任務,當處理完成了就再次把該執行緒放回池中,以供後面的任務使用。當池子裡的執行緒全都處理忙碌狀態時,執行緒池中沒有可用的空閒等待執行緒,此時,根據需要選擇建立乙個新的執行緒並置入池中,或者通知任務執行緒池忙,稍後再試。

我們說,執行緒的建立和銷毀比之程序的建立和銷毀是輕量級的,但是當我們的任務需要大量進行大量執行緒的建立和銷毀操作時,這個消耗就會變成的相當大。比如,當你設計乙個壓力效能測試框架的時候,需要連續產生大量的併發操作,這個是時候,執行緒池就可以很好的幫上你的忙。執行緒池的好處就在於執行緒復用,乙個任務處理完成後,當前執行緒可以直接處理下乙個任務,而不是銷毀後再建立,非常適用於連續產生大量併發任務的場合。

執行緒池的任務就在於負責這些執行緒的建立,銷毀和任務處理引數傳遞、喚醒和等待。

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...