日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > windows >内容正文

windows

操作系统课程设计之Pintos

發(fā)布時(shí)間:2023/12/10 windows 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 操作系统课程设计之Pintos 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

資源下載地址:https://download.csdn.net/download/sheziqiong/86784890
資源下載地址:https://download.csdn.net/download/sheziqiong/86784890

Pintos 的安裝和配置

  • 安裝 qemu
    sudo apt-get install qemu
  • 從 Git 公共庫(kù)獲得最新 Pintos
    git clone git://pintos-os.org/pintos-anon
  • /utils/pintos-gdb 用 VIM 打開(kāi),編輯 GDBMACROS 變量,將 Pintos 完整路徑賦給該變量。
  • 用 VIM 打開(kāi) Makefile 并將 LOADLIBES 變量名編輯為 LDLIBS
  • 在/src/utils 中輸入 make 來(lái)編譯 utils
  • 編輯/src/threads/Make.vars(第 7 行):更改 bochs 為 qemu
  • 在/src/threads 并運(yùn)行來(lái)編譯線程目錄 make
  • 編輯/utils/pintos(第 103 行):替換 bochs 為 qemu
    編輯/utils/pintos(257 行):替換 kernel.bin 為完整路徑的 kernel.bin
    編輯/utils/pintos(621 行):替換 qemu 為 qemu-system-x86_64
    編輯/utils/Pintos.pm(362 行):替換 loader.bin 為完整路徑的 loader.bin
  • 打開(kāi)~/.bashrc 并添加 export PATH=/home/…/pintos/src/utils:$PATH 到最后一行。
  • 重新打開(kāi)終端輸入 source ~/.bashrc 并運(yùn)行
  • 在 Pintos 下打開(kāi)終端輸入 pintos run alarm-multiple
  • Threads

    Mission1

    該部分內(nèi)容主要是需要我們修改 timer_sleep 函數(shù)
    首先查看原本 timer_sleep 代碼

    /* Sleeps for approximately TICKS timer ticks. Interrupts mustbe turned on. */ void timer_sleep (int64_t ticks) { int64_t start = timer_ticks ();ASSERT (intr_get_level () == INTR_ON);while (timer_elapsed (start) < ticks)thread_yield(); }

    通過(guò)查看相關(guān)教程及分析,可知 start 獲取了起始時(shí)間, 然后斷言必須可以被中斷, 不然會(huì)一直死循環(huán)下去。

    while (timer_elapsed (start) < ticks)thread_yield();

    追蹤 thread_yield()函數(shù)及 schedule()函數(shù),schedule 負(fù)責(zé)切換下一個(gè)線程進(jìn)行 run,thread_yield 負(fù)責(zé)把當(dāng)前線程放到就緒隊(duì)列里,然后重新 schedule(當(dāng) ready 隊(duì)列為空時(shí)線程會(huì)繼續(xù)在 CPU 執(zhí)行)。 而 timer_sleep 則是在 ticks 時(shí)間內(nèi),如果線程出于 running 狀態(tài)就不斷把線程放到就緒隊(duì)列不讓他執(zhí)行。由此可以發(fā)現(xiàn)它存在的問(wèn)題:
    線程不斷在 CPU 就緒隊(duì)列和 running 隊(duì)列之間來(lái)回,占用了 CPU 資源。因此我們決定添加喚醒機(jī)制。

    函數(shù)實(shí)現(xiàn)

    修改 thread 結(jié)構(gòu)體:

    struct thread{/* Owned by thread.c. */tid_t tid; /* Thread identifier. */enum thread_status status; /* Thread state. */char name[16]; /* Name (for debugging purposes). */uint8_t *stack; /* Saved stack pointer. */int priority; /* Priority. */struct list_elem allelem; /* List element for all threads list. *//* Shared between thread.c and synch.c. */struct list_elem elem; /* List element. */#ifdef USERPROG/* Owned by userprog/process.c. */uint32_t *pagedir; /* Page directory. */ #endif/* Owned by thread.c. */unsigned magic; /* Detects stack overflow. */int64_t ticks_blocked; /* Time for blocked. */};

    添加了一個(gè)變量 ticks_blocked 用于記錄剩余阻塞時(shí)間。在 timer_sleep 函數(shù)中,將該線程阻塞并設(shè)置阻塞時(shí)間。這一過(guò)程需要解除中斷。
    修改 timer_sleep 函數(shù)

    void timer_sleep (int64_t ticks) {if(ticks <= 0) return;ASSERT (intr_get_level () == INTR_ON);enum intr_level old_level = intr_disable ();struct thread *current_thread = thread_current ();current_thread->ticks_blocked = ticks;thread_block ();intr_set_level (old_level); } ```www.biyezuopin.vipthread_block()的底層是將當(dāng)前線程設(shè)置為 THREAD_BLOCKED 后重新調(diào)度,狀態(tài)為 THREAD_BLOCKED 的線程將從就緒隊(duì)列中移除。 然后在適當(dāng)時(shí)間喚醒線程,在每個(gè) tick 內(nèi)遍歷所有線程,并將 ticks_blocked 值減一,如果該值小于等于 0,則將其從阻塞隊(duì)列中移除并重新調(diào)度。每次時(shí)間片輪轉(zhuǎn)都會(huì)調(diào)度 timer_interrupt 函數(shù)。

    /* Timer interrupt handler. */
    static void
    timer_interrupt (struct intr_frame *args UNUSED)
    {
    ticks++;
    thread_tick ();
    thread_foreach(check_blocked_time,NULL);
    }

    定義 check_blocked_time 函數(shù):將 ticks_blocked 減一,若 ticks_blocked 小于 0,則將其喚醒。```void check_blocked_time(struct thread *t, void *aux){if (t->status == THREAD_BLOCKED && t->ticks_blocked > 0){t->ticks_blocked--;if (t->ticks_blocked == 0)thread_unblock(t);} }

    在頭文件也要添加關(guān)于 check_blocked_time 的聲明

    void check_blocked_time(struct thread *t, void *aux);

    此時(shí) Mission1 通過(guò)部分

    pass tests/threads/alarm-single pass tests/threads/alarm-multiple pass tests/threads/alarm-simultaneous FAIL tests/threads/alarm-priority pass tests/threads/alarm-zero pass tests/threads/alarm-negative

    然后完成線程優(yōu)先級(jí)的問(wèn)題。通過(guò)發(fā)現(xiàn) thread.c 中的 next_thread_to_run()函數(shù),發(fā)現(xiàn)其中存在一個(gè) ready_list。

    static struct thread * next_thread_to_run (void) {if (list_empty (&ready_list))return idle_thread;elsereturn list_entry (list_pop_front (&ready_list), struct thread, elem); }

    查找 list.c 文件,發(fā)現(xiàn)了 list_max 函數(shù),可用于根據(jù)比較函數(shù)查找 ready_list 中優(yōu)先級(jí)最高的線程。構(gòu)造比較函數(shù),利用 list_max 和 list_entry 將優(yōu)先級(jí)最高的線程移除并返回。

    bool thread_compare_priority (const struct list_elem *a,const struct list_elem *b,void *aux UNUSED){return list_entry(a,struct thread,elem)->priority < list_entry(b,struct thread,elem)->priority; } static struct thread * next_thread_to_run (void) {if (list_empty (&ready_list))return idle_thread;else{struct list_elem *max_priority = list_max (&ready_list,thread_compare_priority,NULL);list_remove (max_priority);return list_entry (max_priority,struct thread,elem);} }

    此時(shí),Mission1 部分全部通過(guò)。

    pass tests/threads/alarm-single pass tests/threads/alarm-multiple pass tests/threads/alarm-simultaneous pass tests/threads/alarm-priority pass tests/threads/alarm-zero pass tests/threads/alarm-negative

    Mission2

    從 priority-fifo 測(cè)試看起,改測(cè)試創(chuàng)建了一個(gè)一個(gè)優(yōu)先級(jí) PRI_DEFAULT+2 的主線程,并用這個(gè)線程創(chuàng)建了 16 個(gè)優(yōu)先級(jí) PRI_DEFAULT+1 的子線程,然后把主線程的優(yōu)先級(jí)設(shè)置為優(yōu)先級(jí) PRI_DEFAULT。
    測(cè)試需要把 16 個(gè)線程跑完后結(jié)束主線程,但操作系統(tǒng)中線程是并行執(zhí)行的,有可能最開(kāi)始的一個(gè)線程在設(shè)置完優(yōu)先級(jí)之后立刻結(jié)束了,而此時(shí)其他線程并未結(jié)束。因此在線程設(shè)置完優(yōu)先級(jí)之后應(yīng)該立刻重新調(diào)度,需要在 thread_set_priority()函數(shù)里添加 thread_yield()函數(shù)。

    結(jié)語(yǔ)

    斯坦福操作系統(tǒng)課程設(shè)計(jì)的難度很大,無(wú)論是從環(huán)境的配置和搭建,文檔的查詢(xún)和翻譯,相關(guān)資料的搜集和理解,都需要花費(fèi)很多的功夫。通過(guò) pintos 的自學(xué),我能夠更清晰地理解操作系統(tǒng)中的線程到底是怎么一回事,需要考慮哪些因素:優(yōu)先級(jí)的循環(huán)更新,嵌套調(diào)度,時(shí)間片的考量,關(guān)于線程鎖的概念,以及更復(fù)雜的隊(duì)列調(diào)度算法。受限于時(shí)間原因,這里只完成到 thread 部分。

    資源下載地址:https://download.csdn.net/download/sheziqiong/86784890
    資源下載地址:https://download.csdn.net/download/sheziqiong/86784890

    總結(jié)

    以上是生活随笔為你收集整理的操作系统课程设计之Pintos的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。