多線程:
多進程:能夠同時處理數據(併發/並行)
多線程:能夠同時處理數據(併發/並行)
線程概念:
多進程任務處理(使用的是多個虛擬地址空間):將多個任務分解爲多個程序(分解到多個進程中完成)。
多線程任務處理:多個pcb 共用同一個虛擬地址空間,同時完成一個代碼段中多個不一樣模塊的功能。
進程的理解:只有一個線程的進程
線程的理解:
1.在傳統操做系統中進程就是一個運行中程序中的描述信息 ——>pcb,控制程序的運行
2.linux中並無爲線程設計一個tcb 來控制線程的運行
3.在linux下線程以進程pcb 實現,也就是說,在Linux下pcb 實際是一個線程。
(所以linux下線程:也叫輕量級進程)
(linux下進程:實際是一個線程組——包含一個/多個線程)
由於cpu 調度程序運行是調度pcb ,所以線程時cpu 調度的基本單位
由於一個程序運行起來會分配大量資源給線程組,所以進程是資源分配的基本單位
vfork 由於建立的子進程與父進程共用經過一個虛擬地址空間,所以不能同時運行
而爲何多線程不會出現這個問題?
同一個進程的線程之間獨有的數據:
1.棧
2.寄存器(cpu 上的硬件)
3.errno (錯誤編號)
4.信號屏蔽字(信號阻塞集合)
5.線程id(線程標識符)
同一個進程的線程之間共享的數據:
1.數據段,代碼段
2.文件描述符表
3.信號的處理方式
4.工做路徑
5.用戶id ,組id
多線程與多進程均可以併發完成任務哪個更好?(分析優缺點,視使用場景而定)
多線程的優勢:共享同一個虛擬地址空間
1.線程間的通信更加方便
2.線程的建立銷燬成本更低
3.同一個進程間的線程調度成本更低
4.執行力度更加細緻
多線程的缺點:
1.缺少訪問控制,健壯性低:一些系統調用或異常,針對整個進程產生效果
共同優勢:均可以併發/並行處理任務,提升處理效果
cpu 密集程序:程序中都是大量的運算操做
io 密集程序:程序中都是大量的io 操做
共同缺點:對臨界資源操做須要考慮更多,編碼更加複雜
多進程的使用場景:
對主進程安全都要度特別高——shell(多進程的使用要比多線程安全)
線程控制:
線程建立:
線程控制接口:由於操做系統並無提供直接建立一個線程的接口,就封裝了一套線程接口。所以有人稱
建立的線程是一個用戶態線程,在內核中對應有一個輕量級進程調度程序運行
int pthread_create(pthread_t *thread, const pthread_sttr_t *attr,
void *(*start_routine)(void *), void *arg);
thread:輸出型參數,用於獲取新建立的線程id
attr:線程屬性一般置空
start_routine:線程入口函數
arg:傳遞給線程的參數
返回值:成功返回0;失敗返回:錯誤編號(errno)
每個線程都有一個pcb-task——struct 都有一個pid,可是用戶使用ps -ef命令查看進程的時候只有一個進程,
也只有一個進程pid
查看信息:ps -eflL | head -n 1 && ps -eflL | grep create
LWP:task_struct -> pid
PID:task_struct -> tgid(線程組id) 默認==線程組中主線程pid==進程id
tid:首地址(共享區中線程地址空間的首地址)
線程終止:
線程入口函數中 return, 若是在main 函數中 return 則退出整個進程
void pthread_exit(void* retval) :退出調用線程 retval 通常爲NULL(誰調用誰退出)
線程退出也會造成殭屍進程,由於線程退出也要保存本身的退出返回值
線程退出,也會保存退出返回值,而成爲殭屍進程
主線程退出,進程並不會退出。
取消指定的線程:(被動推出)
int pthread_cancel(pthread_t thread)
thread —>
課後調研:
能不能取消本身?
若是一個線程取消則返回值是多少?
線程等待:獲取指定退出線程的返回值,而且容許操做系統回收線程資源
一個線程啓動後默認右一個屬性是線程處於joinable狀態
*處於joinable狀態的線程,退出後,不會自動釋放資源,須要被其餘線程等待
int pthread_join(pthread_t thread, void **retval);
功能:等待線程退出,獲取返回值,回收線程資源
前提:這個等待的線程必須處於joinable狀態
pthread-> 指定的線程id
retval-> 獲取線程的退出返回值
返回值
成功:0 失敗:錯誤編號(errno)
線程分離:(設置線程的屬性從 joinable 變成 detach 屬性)
功能:分離一個線程,線程退出後系統將自動回收資源,被分離的線程沒法被等待,如果非要pthread_join則會報錯返回
int pthread_detach(pthread_t thread);->能夠在任意位置調用
thread:要被分離的線程id
注意:線程被分離的前提是用戶不關心線程的退出返回值
*處於detach狀態的線程退出後自動回收資源,不須要被等待
*線程默認的屬性是joinable