線程基礎
△ 由於進程的地址空間是私有的,因此在進行上下文切換時,系統開銷比較大
△ 在同一個進程中創建的線程共享該進程的地址空間
△ 通常線程值得是共享相同地址空間的多個任務
△ 每個線程的私有這些私有資源:線程ID、PC(程序計數器)和相關寄存器、棧{局部變量,函數返回地址}、錯誤號、信號掩碼和優先級、執行狀態和屬性
△ 線程間同步和互斥機制有:信號量、互斥鎖、條件變量
1--- 線程相關函數
在Linux中一般通過第三方線程庫來實現: 以下主要是 New POSIX Thread Library (NPTL);
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*routine)(void *), void *arg); //創建一個新線程
thread:要創建的線程 attr:指定的線程屬性, NULL表示缺省屬性 routine:線程中要執行的函數 argv:傳遞給線程執行的函數的參數
返回鍵 成功:0 出錯:錯誤號
int pthread_join(pthread_t thread, void **value_ptr); //等待一個線程的結束
thread:要等待的線程; value_ptr:指針*value_ptr指向線程返回的參數
返回值 成功:0 出錯:錯誤號
void pthread_exit(void *value_ptr); //退出線程
value_ptr:線程退出時的返回值
int pthread_cancel(pthread_t thread); //給線程發送終止信號
thread:要發送信號的進程
2--- 多線程編程示例
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <pthread.h> 5 6 char message[32] = "Hello world"; 7 void *thread_function(void *arg); 8 9 int main(int argc, char *argv[]) 10 { 11 pthread_t a_thread; 12 void *thread_result; 13 14 if (pthread_create(&a_thread, NULL, thread_function, (void *)message) < 0); //使用缺省屬性創建線程 15 { 16 perror("fail to pthread create"); 17 exit(-1); 18 } 19 printf("waiting for thread to finish\n"); 20 if (pthread_join(a_thread, &thread_result) < 0) //等待線程結束 21 { 22 perror("fail to pthread join"); 23 exit(-1); 24 } 25 printf("MESSAGE is now %s\n", message); 26 27 return 0; 28 } 29 30 void *thread_function(void *arg) 31 { 32 33 srtcpy(message, "marked by thread"); 34 pthread_exit("Thank you for the cpu time"); 35 }
3--- 編譯多線程程序
# gcc -o sample sample.c -lpthread -D_REENTRANT
-lpthred:;鏈接pthread庫
-D_REENTRANT:生成可重入代碼
pthread_key_create(); 線程私有數據 unix/linux下線程私有數據實現原理及使用方法
4--- 線程池 thread_pool
大多數的網絡服務器,包括Web服務器都具有一個特點,就是單位時間內必須處理數目巨大的連接請求,但是處理時間卻是比較短的。在傳統的多線程服務器模型中是這樣實現的:一旦有個請求到達,就創建一個新的線程,由該線程執行任務,任務執行完畢之后,線程就退出。這就是"即時創建,即時銷毀"的策略。盡管與創建進程相比,創建線程的時間已經大大的縮短, 但是如果提交給線程的任務是執行時間較短,而且執行次數非常頻繁,那么服務器就將處於一個不停的創建線程和銷毀線程的狀態。這筆開銷是不可忽略的,尤其是線程執行的時間非常非常短的情況。
線程池就是為了解決上述問題的,它的實現原理是這樣的:在應用程序啟動之后,就馬上創建一定數量的線程,放入空閑的隊列中。這些線程都是處於阻塞狀態,這些線程只占一點內,不占用CPU。當任務到來后,線程池將選擇一個空閑的線程,將任務傳入此線程中運行。當所有的線程都處在處理任務的時候,線程池將自動創建一定的數量的新線程,用於處理更多的任務。執行任務完成之后線程並不退出,而是繼續在線程池中等待下一次任務。當大部分線程處於阻塞狀態時,線程池將自動銷毀一部分的線程,回收系統資源。
下面是一個簡單線程池的實現,這個線程池的代碼是我參考網上的一個例子實現的,由於找不到出處了,就沒辦法注明參考自哪里了。它的方案是這樣的:程序啟動之前,初始化線程池,啟動線程池中的線程,由於還沒有任務到來,線程池中的所有線程都處在阻塞狀態,當一有任務到達就從線程池中取出一個空閑線程處理,如果所有的線程都處於工作狀態,就添加到隊列,進行排隊。如果隊列中的任務個數大於隊列的所能容納的最大數量,那就不能添加任務到隊列中,只能等待隊列不滿才能添加任務到隊列中。
實現代碼:簡單Linux線程池 http://www.cnblogs.com/venow/archive/2012/11/22/2779667.html