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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

操作系统课程设计之Pintos

發布時間:2023/12/10 windows 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 操作系统课程设计之Pintos 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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

Pintos 的安裝和配置

  • 安裝 qemu
    sudo apt-get install qemu
  • 從 Git 公共庫獲得最新 Pintos
    git clone git://pintos-os.org/pintos-anon
  • /utils/pintos-gdb 用 VIM 打開,編輯 GDBMACROS 變量,將 Pintos 完整路徑賦給該變量。
  • 用 VIM 打開 Makefile 并將 LOADLIBES 變量名編輯為 LDLIBS
  • 在/src/utils 中輸入 make 來編譯 utils
  • 編輯/src/threads/Make.vars(第 7 行):更改 bochs 為 qemu
  • 在/src/threads 并運行來編譯線程目錄 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
  • 打開~/.bashrc 并添加 export PATH=/home/…/pintos/src/utils:$PATH 到最后一行。
  • 重新打開終端輸入 source ~/.bashrc 并運行
  • 在 Pintos 下打開終端輸入 pintos run alarm-multiple
  • Threads

    Mission1

    該部分內容主要是需要我們修改 timer_sleep 函數
    首先查看原本 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(); }

    通過查看相關教程及分析,可知 start 獲取了起始時間, 然后斷言必須可以被中斷, 不然會一直死循環下去。

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

    追蹤 thread_yield()函數及 schedule()函數,schedule 負責切換下一個線程進行 run,thread_yield 負責把當前線程放到就緒隊列里,然后重新 schedule(當 ready 隊列為空時線程會繼續在 CPU 執行)。 而 timer_sleep 則是在 ticks 時間內,如果線程出于 running 狀態就不斷把線程放到就緒隊列不讓他執行。由此可以發現它存在的問題:
    線程不斷在 CPU 就緒隊列和 running 隊列之間來回,占用了 CPU 資源。因此我們決定添加喚醒機制。

    函數實現

    修改 thread 結構體:

    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. */};

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

    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()的底層是將當前線程設置為 THREAD_BLOCKED 后重新調度,狀態為 THREAD_BLOCKED 的線程將從就緒隊列中移除。 然后在適當時間喚醒線程,在每個 tick 內遍歷所有線程,并將 ticks_blocked 值減一,如果該值小于等于 0,則將其從阻塞隊列中移除并重新調度。每次時間片輪轉都會調度 timer_interrupt 函數。

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

    定義 check_blocked_time 函數:將 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);} }

    在頭文件也要添加關于 check_blocked_time 的聲明

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

    此時 Mission1 通過部分

    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

    然后完成線程優先級的問題。通過發現 thread.c 中的 next_thread_to_run()函數,發現其中存在一個 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 文件,發現了 list_max 函數,可用于根據比較函數查找 ready_list 中優先級最高的線程。構造比較函數,利用 list_max 和 list_entry 將優先級最高的線程移除并返回。

    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);} }

    此時,Mission1 部分全部通過。

    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 測試看起,改測試創建了一個一個優先級 PRI_DEFAULT+2 的主線程,并用這個線程創建了 16 個優先級 PRI_DEFAULT+1 的子線程,然后把主線程的優先級設置為優先級 PRI_DEFAULT。
    測試需要把 16 個線程跑完后結束主線程,但操作系統中線程是并行執行的,有可能最開始的一個線程在設置完優先級之后立刻結束了,而此時其他線程并未結束。因此在線程設置完優先級之后應該立刻重新調度,需要在 thread_set_priority()函數里添加 thread_yield()函數。

    結語

    斯坦福操作系統課程設計的難度很大,無論是從環境的配置和搭建,文檔的查詢和翻譯,相關資料的搜集和理解,都需要花費很多的功夫。通過 pintos 的自學,我能夠更清晰地理解操作系統中的線程到底是怎么一回事,需要考慮哪些因素:優先級的循環更新,嵌套調度,時間片的考量,關于線程鎖的概念,以及更復雜的隊列調度算法。受限于時間原因,這里只完成到 thread 部分。

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

    總結

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

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。