資源描述:
《pintos操作系統(tǒng)實(shí)驗(yàn)一》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在教育資源-天天文庫(kù)。
1、操作系統(tǒng)課程實(shí)驗(yàn)TA:林璋瑋彭禹惟馮善恒李宏釗課程計(jì)劃第5周:實(shí)驗(yàn)環(huán)境安裝與搭建(part0)第6~7周:線程的休眠與喚醒(part1)第8~9周:優(yōu)先級(jí)調(diào)度(part2)第10~11周:線程鎖、信號(hào)量與優(yōu)先級(jí)繼承(part3)第12~14周:多級(jí)反饋隊(duì)列調(diào)度(part4)實(shí)驗(yàn)一.Non-busywaiting通過修改pintos的線程休眠函數(shù)來(lái)保證pintos不會(huì)在一個(gè)線程休眠時(shí)忙等待。相關(guān)文件pintos/src/devices目錄:timer.h,timer.cpintos/src/threads目錄:thread.
2、h,thread.c需要閱讀相關(guān)結(jié)構(gòu)體以及函數(shù)。Pintos的機(jī)制出于安全性等考慮,每隔一段時(shí)間操作系統(tǒng)必須獲得CPU時(shí)間,進(jìn)行進(jìn)程調(diào)度等工作。而操作系統(tǒng)是通過中斷來(lái)獲得CPU時(shí)間pintos中操作系統(tǒng)中斷頻率為、Pintos的機(jī)制Timer中斷產(chǎn)生時(shí)這個(gè)函數(shù)就會(huì)被調(diào)用。中斷相關(guān)pintos/src/threads目錄:interrupt.c和interrupt.h該枚舉定義了中斷是開還是關(guān),在原子操作中必須保證中斷是關(guān)的。用函數(shù)interrupt_disable()來(lái)關(guān)閉中斷。threadPintos中定義了一個(gè)thre
3、ad的結(jié)構(gòu)體用于存儲(chǔ)線程的信息(包括優(yōu)先級(jí),狀態(tài)等),位于thread.h。其中thread有四個(gè)狀態(tài):Thread這個(gè)結(jié)構(gòu)體貫穿整個(gè)實(shí)驗(yàn)。thread線程休眠timer.c中實(shí)現(xiàn)了線程休眠的函數(shù)thread_sleep這個(gè)函數(shù)作用是讓線程休眠一定的時(shí)間。ASSERT作用是若語(yǔ)句不為真則退出。線程休眠時(shí)必須保證中斷是打開的。線程休眠thread_sleep的實(shí)現(xiàn)原理是通過不斷輪詢檢查經(jīng)過時(shí)間是否達(dá)到ticks,若還沒達(dá)到則調(diào)用thread_yield函數(shù),達(dá)到了ticks就會(huì)結(jié)束休眠。thread_yield該函數(shù)會(huì)把當(dāng)前
4、線程放進(jìn)ready隊(duì)列,并調(diào)度下一個(gè)線程,線程調(diào)度時(shí)要保證中斷關(guān)閉。schedule專門負(fù)責(zé)線程切換的函數(shù),執(zhí)行了以后會(huì)把當(dāng)前線程放進(jìn)隊(duì)列里并調(diào)度出下一個(gè)線程。線程休眠問題?Thread_yield函數(shù)只是把線程放進(jìn)調(diào)度隊(duì)列,然后切換線程,此時(shí)休眠線程狀態(tài)是ready,在一個(gè)tick內(nèi)依然有可能會(huì)被調(diào)度,繼續(xù)消耗cpu時(shí)間,沒有完全把時(shí)間讓給別的進(jìn)程,這樣就違反了線程休眠的原則,造成了忙等待。目標(biāo)通過重新設(shè)計(jì)thread_sleep函數(shù)讓休眠線程不再占用cpu時(shí)間,只在每次tick中斷把時(shí)間交給操作系統(tǒng)時(shí)再檢查睡眠時(shí)間,t
5、ick內(nèi)則把cpu時(shí)間讓給別的線程。解決辦法1.重寫timer_sleep函數(shù),不是調(diào)用thread_yield而是調(diào)用thread_block函數(shù)把線程block了,這樣在unblock之前該線程都不會(huì)被調(diào)度執(zhí)行。2.Thread結(jié)構(gòu)體中新增成員變量ticks_blocked,記錄線程剩余睡眠的時(shí)間(單位:tick)。初始化為0,在timer_sleep函數(shù)中把tick賦值為睡眠時(shí)間。解決辦法3.thread.c中增加函數(shù)checkInvoke判斷線程是否休眠完畢(ticks_blocked的值)。4.處理timer中斷
6、時(shí)(timer_interrupt)遍歷所有線程(thread_for_each,詳細(xì)見代碼)并判斷被block線程是否睡眠完畢,睡眠完畢則喚醒。解決辦法完成上述步驟以后,大部分的alarm測(cè)試都通過了。但是alarm_priority依然還沒通過。接下來(lái)介紹解決alarm_priority的知識(shí)。listList的結(jié)構(gòu),list中存放的數(shù)據(jù)類型是list_elem,存放待執(zhí)行線程靠的就是list。Thread與list有一個(gè)list變量ready_list專門存放待執(zhí)行的線程,由于list存放的是list_elem類型,
7、因此thread中有一個(gè)成員變量專門用于在ready_list中“排隊(duì)”。Thread與list既然在ready_list中并不是thread而只是thread的一個(gè)成員,怎么通過list中的elem來(lái)訪問對(duì)應(yīng)線程的其他變量?List中已經(jīng)提供了一個(gè)宏定義解決這個(gè)問題。解決辦法alarm-priority要求線程是根據(jù)優(yōu)先級(jí)進(jìn)行調(diào)度的,而pintos的基本實(shí)現(xiàn)是直接把線程放進(jìn)ready_list尾部,是FIFO的調(diào)度方式。如果要通過這個(gè)測(cè)試就必須保證在ready_list中線程是有序的。hints:使用list_inser
8、t_order函數(shù)可以保證有序插入。注意事項(xiàng)1.先閱讀源代碼和測(cè)試的代碼。把握線程的整體結(jié)構(gòu),以后做實(shí)驗(yàn)也會(huì)輕松一點(diǎn)。2.調(diào)用函數(shù)前要看看該函數(shù)是否要求關(guān)閉或者打開中斷。3.修改前最好備份一下。成功標(biāo)志makecheck中通過所有的alarm測(cè)試!報(bào)告要求1.回答問題:(1).為什么未經(jīng)修改仍能通過一些