1、什么是可重入函數(shù)
可重入函數(shù)是指能夠被多個(gè)線程“同時(shí)”調(diào)用的函數(shù)(線程安全),并且能夠保證結(jié)果的正確性的函數(shù)。
在C語言中編寫可重入函數(shù)時(shí),盡量不使用全局變量和靜態(tài)變量。如果使用了,則在線程中對(duì)這類變量訪問時(shí),要注意對(duì)其訪問的互斥。一般,可以采用以下幾種措施來保證函數(shù)的可重用:信號(hào)量機(jī)制、關(guān)調(diào)度機(jī)制、關(guān)中斷機(jī)制。
需要注意的是,不要調(diào)用不可重入的函數(shù)。一旦調(diào)用,則會(huì)使得該函數(shù)也變得不可重入。一般驅(qū)動(dòng)程序都是不可重入函數(shù),因此在編寫驅(qū)動(dòng)程序時(shí)一定要注意重入問題。
2、線程相關(guān)
線程有時(shí)候被稱為輕量級(jí)進(jìn)程(LWP),是程序執(zhí)行流中最小的單位。線程是進(jìn)程中的實(shí)體,是被系統(tǒng)獨(dú)立調(diào)度和分派的基本單位,不擁有自己的資源,只擁有一些必不可小的資源,可與進(jìn)程中其他線程共享所擁有的資源。
一個(gè)線程獨(dú)立 的部分包括線程ID,當(dāng)前指針(PC),寄存器集合,堆棧,錯(cuò)誤返回碼,信號(hào)屏蔽碼,線程優(yōu)先級(jí)。
引入線程后的進(jìn)程只作為除CPU外,系統(tǒng)資源的分配單元線程則作為處理器的分配單元。同一進(jìn)程切換線程不會(huì)引起進(jìn)程切換,但一個(gè)進(jìn)程的切換到另一個(gè)進(jìn)程的線程則會(huì)引起進(jìn)程的切換。
3、臨界區(qū)與互斥量的區(qū)別
1)臨界區(qū)只能用來同步進(jìn)程內(nèi)的線程,而不可用來同步多個(gè)進(jìn)程中的線程:互斥量,事件都可以被跨進(jìn)程使用來同步數(shù)據(jù)操作。
2)臨界區(qū)是非內(nèi)核對(duì)象,只能用在用戶態(tài)進(jìn)行鎖操作,速度快;互斥體是內(nèi)核對(duì)象,在和心態(tài)進(jìn)行鎖操作,速度慢。
3)互斥體在Windows和Linux下都有,臨界區(qū)只在Windows平臺(tái)下可用。
4、地址重定位
當(dāng)裝入程序?qū)⒖蓤?zhí)行代碼裝入內(nèi)存時(shí),必須通過地址轉(zhuǎn)換將邏輯地址轉(zhuǎn)化為物理地址,這個(gè)過程稱為地址重定位。
5、分段,分頁,段頁
基本分段存儲(chǔ)管理:段內(nèi)要求連續(xù),段間不要求連續(xù)。段式系統(tǒng)中,段號(hào)和段內(nèi)偏移必須由用戶顯示提供,在高級(jí)設(shè)計(jì)語言中,這個(gè)工作由編譯程序完成,整個(gè)作業(yè)的地址空間是二維的。
基本分頁系統(tǒng)中,邏輯地址的頁號(hào)和頁內(nèi)偏移對(duì)用戶是透明的。
段頁式系統(tǒng)中,邏輯地址分為三個(gè)部分:段號(hào),頁號(hào),頁內(nèi)偏移量。為實(shí)現(xiàn)地址變換,系統(tǒng)為每一個(gè)進(jìn)程建立一張段表,而每個(gè)分段有一張頁表。
6、如何減少頻繁分配內(nèi)存造成的內(nèi)存碎片
內(nèi)存池(Memory Pool)是一種內(nèi)存分配方式。通常,我們使用new malloc 分配內(nèi)存,但頻繁使用會(huì)造成大量的內(nèi)存碎片,并降低性能。內(nèi)存池是在真正使用內(nèi)存之前,先申請(qǐng)一定數(shù)量的,大小相等的(一般情況下)的內(nèi)存留作備用,當(dāng)新需求到來時(shí),就從內(nèi)存池中分配一部分內(nèi)存塊,若不夠再繼續(xù)申請(qǐng)新的內(nèi)存,避免了內(nèi)存碎片,提高了效率。
7、內(nèi)存泄漏與緩沖區(qū)溢出
內(nèi)存泄漏是指沒有用相應(yīng)方式釋放已經(jīng)不再使用的內(nèi)存,導(dǎo)致該快內(nèi)存無法被再次使用。
緩沖區(qū)溢出是指緩沖區(qū)數(shù)據(jù)位超過了緩沖區(qū)本身的容量。由于絕大多數(shù)程序都會(huì)假設(shè)數(shù)據(jù)長度總與分配空間相匹配,這就為緩沖區(qū)溢出埋下隱患。例如strcpy,sprintf等。緩沖區(qū)溢出是導(dǎo)致黑客型病毒橫行的重要原因。
8、什么是線程安全
如果多線程程序運(yùn)行結(jié)果是可預(yù)期的,而且與單線程運(yùn)行結(jié)果一樣,那么說明“線程安全”。
9、多線程同步和互斥有幾種方法實(shí)現(xiàn)
臨界區(qū)(critical section)、事件(event)、互斥量(mutex)、信號(hào)量(semaphores)、條件變量。臨界區(qū)是效率最高的,因?yàn)椴恍枰渌_銷。
10、死鎖的必要條件與處理
互斥條件,請(qǐng)求和保持,不可剝奪,循環(huán)等待
死鎖處理方案:
1)預(yù)防死鎖:通過設(shè)置某些條件去破壞產(chǎn)生死鎖的一個(gè)或幾個(gè)條件來防止死鎖。但,由于限制條件往往太嚴(yán)格,導(dǎo)致資源利用率和系統(tǒng)吞吐率低。
2)避免死鎖:不事先采取限制措施,而是在資源動(dòng)態(tài)分配過程中,用某種方法防止系統(tǒng)進(jìn)入不安全狀態(tài),從而避免死鎖。銀行家算法是常見避免死鎖算法。
3)檢測死鎖,設(shè)置檢測機(jī)構(gòu)及時(shí)檢測死鎖,不事先采取任何措施
4)與檢測死鎖配套使用,將進(jìn)程從死鎖狀態(tài)中解脫出來,常用的方法是撤銷或掛起一些進(jìn)程。
11、上下文切換
為了控制進(jìn)程的執(zhí)行,內(nèi)核必須有能力掛起正在CPU上運(yùn)行的進(jìn)程,并恢復(fù)以前掛起的某個(gè)進(jìn)程的執(zhí)行。這種行為被稱為進(jìn)程切換。因此可以說,任何進(jìn)程都是在操作系統(tǒng)內(nèi)核的支持下運(yùn)行的,是與內(nèi)核緊密相關(guān)的。
從一個(gè)進(jìn)程的運(yùn)行轉(zhuǎn)到另一個(gè)進(jìn)程上運(yùn)行,這個(gè)過程中經(jīng)過下面這些變化:
- 保存處理機(jī)上下文,包括程序計(jì)數(shù)器和其他寄存器。
- 更新PCB信息。
- 把進(jìn)程的PCB移入相應(yīng)的隊(duì)列,如就緒、在某事件阻塞等隊(duì)列。
- 選擇另一個(gè)進(jìn)程執(zhí)行,并更新其PCB。
- 更新內(nèi)存管理的數(shù)據(jù)結(jié)構(gòu)。
- 恢復(fù)處理機(jī)上下文。
12、進(jìn)程與線程的區(qū)別
進(jìn)程是具有一定獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合的依次運(yùn)行活動(dòng),它是操作系統(tǒng)資源分配的基本單位。線程又稱為輕量級(jí)線程,是CPU調(diào)度和分配的基本單位。
二者區(qū)別主要有:
1、關(guān)系:一個(gè)線程必定屬于一個(gè)進(jìn)程,一個(gè)進(jìn)程可以擁有多個(gè)線程。
2、資源:進(jìn)程擁有自己的資源,一個(gè)進(jìn)程的所有線程共享該進(jìn)程的所有資源,包括打開的文件,創(chuàng)建的socket等。不同進(jìn)程間相互獨(dú)立。線程只擁有運(yùn)行時(shí)必不可少的資源。
3、并發(fā):線程間切換開銷小,效率高,提高了并發(fā)性。
4、健壯:線程有自己的堆棧和局部變量,但線程之間沒有單獨(dú)的地址空間,一個(gè)線程崩潰將影響該進(jìn)程內(nèi)其他線程,多進(jìn)程的程序要比多線程的程序健壯。
13、內(nèi)核線程和用戶線程的區(qū)別
根據(jù)操作系統(tǒng)內(nèi)核是否可感知,可把線程分為內(nèi)核線程和用戶線程。
內(nèi)核線程的建立和銷毀都是由操作系統(tǒng)負(fù)責(zé)的,通過系統(tǒng)調(diào)用完成。在操作系統(tǒng)調(diào)用時(shí),參考各進(jìn)程內(nèi)的線程情況作出調(diào)度決定。如果一個(gè)進(jìn)程沒有就緒態(tài)的線程,那么這個(gè)進(jìn)程也不會(huì)調(diào)度占用CPU。
與內(nèi)核線程相對(duì)的是用戶線程,用戶線程指不需要內(nèi)核支持,而在用戶程序中實(shí)現(xiàn)的線程,其不依賴于操作系統(tǒng)的核心,用戶利用線程庫創(chuàng)建,調(diào)度,同步,和管理線程。
引入用戶線程的優(yōu)點(diǎn):
1、可以在不支持線程的操作系統(tǒng)中實(shí)現(xiàn)
2、創(chuàng)建、銷毀、切換線程不需要經(jīng)過用戶態(tài)、內(nèi)核態(tài)的切換,因此代價(jià)低,效率高
3、允許每個(gè)進(jìn)程定制自己的調(diào)度算法,線程管理比較靈活
4、線程能利用的表空間和堆空間比內(nèi)核級(jí)線程多
用戶線程的缺點(diǎn):
1、同一個(gè)進(jìn)程只能有一個(gè)線程在運(yùn)行,如果有一個(gè)線程使用了系統(tǒng)調(diào)用而阻塞,那么整個(gè)進(jìn)程都會(huì)被掛起。
2、頁面失效也會(huì)導(dǎo)致整個(gè)進(jìn)程被掛起。
13、庫函數(shù)與系統(tǒng)調(diào)用的區(qū)別
庫函數(shù)調(diào)用是語言或應(yīng)用程序的一部分,它是高層的,完全運(yùn)行在用戶空間,是為程序員提供實(shí)際事務(wù)操作的調(diào)用接口。
系統(tǒng)函數(shù)則是內(nèi)核提供給應(yīng)用程序的接口,屬于系統(tǒng)的一部分。函數(shù)調(diào)用是語言或應(yīng)用程序的一部分,而系統(tǒng)調(diào)用是操作系統(tǒng)的一部分。
庫函數(shù)調(diào)用通常比行內(nèi)展開的代碼慢,因?yàn)樗枰冻龊瘮?shù)調(diào)用的開銷。但,系統(tǒng)調(diào)用比庫函數(shù)調(diào)用還慢得多,因?yàn)樾枰M(jìn)行進(jìn)行兩次上下文環(huán)境切換。