1.線程的概念
進(jìn)程概念
是處于執(zhí)行期的程序以及它所管理的資源(如打開的文件、掛起的信號、進(jìn)程狀態(tài)、地址空間等等)的總稱,從操作系統(tǒng)核心角度來說,進(jìn)程是操作系統(tǒng)調(diào)度除CPU時間片外進(jìn)行的資源分配和保護(hù)的基本單位,它有一個獨(dú)立的虛擬地址空間,用來容納進(jìn)程映像(如與進(jìn)程關(guān)聯(lián)的程序與數(shù)據(jù)),并以進(jìn)程為單位對各種資源實施保護(hù),如受保護(hù)地訪問處理器、文件、外部設(shè)備及其他進(jìn)程(進(jìn)程間通信),linux系統(tǒng)都是通過task_struct結(jié)構(gòu)來管理的,task_struct也被稱為“進(jìn)程描述符”。
最后,如果大家如果在自學(xué)遇到困難,想找一個C++的學(xué)習(xí)環(huán)境,可以加入我們的C++學(xué)習(xí)圈,點擊我加入吧,會節(jié)約很多時間,減少很多在學(xué)習(xí)中遇到的難題。
線程是在進(jìn)程中產(chǎn)生的一個執(zhí)行單元,是CPU調(diào)度和分配的最小單元,其在同一個進(jìn)程中與其他線程并行運(yùn)行,他們可以共享進(jìn)程內(nèi)的資源,比如內(nèi)存、地址空間、打開的文件等等。
線程是CPU調(diào)度和分派的基本單位,
進(jìn)程是分配資源的基本單位。
那到底如何理解進(jìn)程和線程呢?
假定工廠的電力有限,一次只能供給一個或少量幾個車間使用。也就是說,一部分車間開工的時候,其他車間都必須停工。背后的含義就是,單個CPU一次只能運(yùn)行一個任務(wù),多個CPU能夠運(yùn)行少量任務(wù)。
進(jìn)程就好比工廠的車間,它代表CPU所能處理的單個任務(wù)。就好比工廠給與車間配備一定的裝備、辦公場所和工人。
一個車間里,可以有很多工人。他們協(xié)同完成一個任務(wù)。
線程就好比車間里的工人。一個進(jìn)程可以包括多個線程,他們協(xié)同完成某一個任務(wù)。
線程是CPU調(diào)度和分派的基本單位,而進(jìn)程是分配資源的基本單位。
創(chuàng)建線程的方法
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
Thread : 線程標(biāo)識符;
attr:線程的屬性,如果為NULL表示使用默認(rèn)的屬性值,一般填寫NULL就夠了,默認(rèn)的屬性為非綁定、非分離、缺省的堆棧、與父進(jìn)程同樣級別的優(yōu)先級。對屬性的設(shè)置在創(chuàng)建線程之前,先用pthread_attr_init初始化,然后調(diào)用相關(guān)接口設(shè)置屬性,
√__detachstate:分離性,表示新線程是否與進(jìn)程中其他線程脫離同步。
√__schedpolicy:主要包括SCHED_OTHER(正常、非實時)、SCHED_RR(實時、輪轉(zhuǎn)法)和SCHED_FIFO(實時、先入先出)三種,缺省為SCHED_OTHER,后兩種調(diào)度策略僅對超級用戶有效。運(yùn)行時可以用過pthread_setschedparam()來改變。
√__schedparam:設(shè)置線程的優(yōu)先級。SCHED_OTHER是不支持優(yōu)先級使用的,而SCHED_FIFO和SCHED_RR支持優(yōu)先級的使用,他們分別為1和99,數(shù)值越大優(yōu)先級越高。是不是優(yōu)先級越高就一定優(yōu)先執(zhí)行?
√__inheritsched:表示是否采用__schedpolicy指定的調(diào)度策略。
√__scope:綁定性,牽扯到輕進(jìn)程的概念,線程的調(diào)用實際是依附在輕進(jìn)程上調(diào)用的。
start_routine : 線程函數(shù)的名
arg:傳遞給start_routine的參數(shù)
成功返回0,否則返回錯誤碼,此時thread的值是未被定義的
線程的終止
√ 從線程函數(shù)return,這是最推薦的辦法。
√ 一個線程可以調(diào)用pthread_cancel終止同一進(jìn)程中的另一個線程:
int pthread_cancel(pthread_t thread);
√ 線程可以調(diào)pthread_exit終自己;
√ 調(diào)用pthread_kill發(fā)送一個信號終止同一進(jìn)程中的另一個線程;
線程的回收
int pthread_join(pthread_t tid, void **status);
pthread_join()函數(shù)會一直阻塞調(diào)用線程,直到指定的線程tid終止。當(dāng)pthread_join()返回之后,應(yīng)用程序可回收與已終止線程關(guān)聯(lián)的任何數(shù)據(jù)存儲空間,但是還有一些線程,更喜歡自己來清理退出 的狀態(tài),他們也不愿意主線程調(diào)用pthread_join來等待他們。我們將這一類線程的屬性稱為detached(分離的)。
2.為什么需要多線程
避免阻塞
大家知道,單個進(jìn)程只有一個主線程,當(dāng)主線程阻塞的時候,整個進(jìn)程也就阻塞了,無法再去做其它的一些功能了。
避免CPU空轉(zhuǎn)
應(yīng)用程序經(jīng)常會涉及到RPC,數(shù)據(jù)庫訪問,磁盤IO等操作,這些操作的速度比CPU慢很多,而在等待這些響應(yīng)時,CPU卻不能去處理新的請求,導(dǎo)致這種單線程的應(yīng)用程序性能很差。
提升效率
一個進(jìn)程要獨(dú)立擁有4GB的虛擬地址空間,而多個線程可以共享同一地址空間,線程的切換比進(jìn)程的切換要快得多。
3.多線程會帶來什么問題
車間的空間是工人們共享的,比如許多房間是每個工人都可以進(jìn)出的。這象征一個進(jìn)程的內(nèi)存空間是共享的,每個線程都可以使用這些共享內(nèi)存。
如果一個廁所只能容納一個人,那有多個人要上廁所怎么辦?
也就是說對多個線程共享的內(nèi)存進(jìn)行讀寫時需要做好某種機(jī)制使得有秩序低訪問。
由于內(nèi)容太多,已經(jīng)為大家整理好PDF文檔。以下資料,需要的關(guān)注,私信:“資料”