linux下執行緒原理及實現

2021-08-02 00:16:28 字數 3475 閱讀 5511

什麼是執行緒池?

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

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

簡單執行緒池的實現

3.、實現了上面二步,乙個執行緒池的框架就初步搭起來了。當然沒法用,因為真正幹事情的執行緒全部在等待中,注意不應該是超時的等待pthread_cond_timewait()。要使處於阻塞狀態的執行緒幹事情,得用訊號去喚醒它pthread_cond_signal(),「打鳥」的乙個函式,開一槍,總會把這只鳥吵醒,但具體是那乙隻,看那只最先在那排隊了(上面已經說了pthread_cond_wait()函式的等待佇列問題)。當然也可以想到「打鳥驚群」的函式pthread_cond_broadcast(),打一槍,無論打沒打著,一群鳥都飛走了。

4、有了上面的基礎,接下來就重點關注任務部分了。當然執行緒數量有限,上面已經說了,是固定的數目。因此任務大於執行緒數時,排隊是難免的了。因此建立了乙個任務佇列,佇列中的每一項代表乙個任務。任務佇列的節點最簡單的模型就是乙個處理任務的回掉函式void* (*callback_function)(void *arg)。指向函式的指標,引數是個指標,返回值也是個指標。具體的函式和引數則需要另外寫函式定義。沒次呼叫完執行緒處理完這個任務,就需要把它從任務佇列中刪除。進入任務佇列的任務數也不能無限多,因此也設為乙個比執行緒數稍微大個幾個的乙個固定值。

5、執行緒動態建立:乙個執行緒退出後(在任務執行失敗時,就有可能會退出),主線程要能檢測到,然後動態建立乙個新的執行緒,以維持執行緒池中線程總數不變。可以通過pthread_join()阻塞等待**子執行緒資源,但是這就意味著主線程在阻塞狀態下幹不了其他工作,因此考慮使用執行緒訊號,在子執行緒結束時,給主線程用pthread_kill()傳送乙個sigusr1訊號,在主線程接收到此訊號時,通過呼叫註冊函式signal()或sigaction()函式註冊的函式建立乙個新的執行緒。

//threadpool設計    

void *thread_routine(void *args);

class threadpool

;

public:

threadpool(int _maxthreads = 36, unsigned int _waitseconds = 2);

~threadpool();

//新增任務介面

void addtask(callback_t run, void *args);

private:

void starttask();

private:

condition ready; //任務準備就緒或執行緒池銷毀通知

std::queuetaskqueue; //任務佇列

unsigned int maxthreads; //執行緒池最多允許的執行緒數

unsigned int counter; //執行緒池當前執行緒數

unsigned int idle; //執行緒池空閒執行緒數

unsigned int waitseconds; //執行緒可以等待的秒數

bool quit; //執行緒池銷毀標誌

};

// 執行緒入口函式    

// 這其實就相當於乙個消費者執行緒, 不斷的消費任務(執行任務)

void *thread_routine(void *args)

}

//條件成熟(當等待結束), 執行緒開始執行任務或者是執行緒銷毀, 則說明空閒執行緒又少了乙個

-- pool->idle;

// 狀態3.如果等待超時(一般此時任務佇列已經空了)

if (timeout == true && pool->taskqueue.empty())

// 狀態2.如果是等待到了執行緒的銷毀通知, 且任務都執行完畢了

if (pool->quit == true && pool->taskqueue.empty())

// 狀態1.如果是有任務了, 則執行任務

if (!(pool->taskqueue.empty()))

}

//跳出迴圈之後, 列印退出資訊, 然後銷毀執行緒

printf("thread 0x%lx is exiting...\n", (unsigned long)pthread_self());

pthread_exit(null);

}

//addtask函式    

//新增任務函式, 類似於乙個生產者, 不斷的將任務生成, 掛接到任務佇列上, 等待消費者執行緒進行消費

void threadpool::addtask(callback_t run, void *args)

;

ready.lock(); //注意需要使用互斥量保護共享變數

taskqueue.push(newtask);

/** 2. 讓執行緒開始執行任務 **/

starttask();

ready.unlock();//解鎖以使任務開始執行

}

//執行緒啟動函式    

void threadpool::starttask()

}

//析構函式    

threadpool::~threadpool()

ready.unlock();

}

Linux下執行緒實現

1.執行緒概述 程序是系統中程式執行和資源分配的基本單位。每個程序有自己的資料段 段和堆疊段。執行緒通常叫做輕型的程序。執行緒是在共享記憶體空間中併發執行的多道執行路徑,他們共享乙個程序的資源。因為執行緒和程序比起來很小,所以相對來說,執行緒花費更少的cpu資源。2.執行緒建立和退出 在linux中...

Linux下執行緒

此文講述的執行緒為linux下,其執行緒庫函式是由posix標準定義的,稱為posix thread或者pthread。在linux上線程函式位於libpthread共享庫中,因此在編譯時要加上 lpthread選項。建立執行緒 終止執行緒 等待執行緒 三個函式都為pthread.h中定義,其中要注...

linux下執行緒池的實現(c )

2012 12 07 16 11 44 分類 電子安防專案 舉報 字型大小訂閱 參考 autoptr.h created on 2012 12 7 author kym 智慧型指標模板 ifndef autoptr h define autoptr h include template class ...