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ù)長(zhǎng)度總與分配空間相匹配,這就為緩沖區(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)檢測(cè)死鎖生音,設(shè)置檢測(cè)機(jī)構(gòu)及時(shí)檢測(cè)死鎖,不事先采取任何措施
4)與檢測(cè)死鎖配套使用窒升,將進(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)境切換喉磁。