Try   HackMD

Linux 核心專題: 重作第一次作業

執行人: brucelee503jo3
專題解說影片

任務簡介

重作第一次作業,並強化以下:

  • 使用 select, poll 系統呼叫來處理 I/O multiplexing,從而改進原本網頁伺服器的效能
  • 亂數和相關統計描述
  • 改進常數時間判定

TODO: 以 I/O multiplexing 改進網頁伺服器的效能

詳閱 Linux 核心設計: 針對事件驅動的 I/O 模型演化
維持單執行緒的狀況下,改進內建網頁伺服器的效能,過程中應進行量化分析。

在這項任務中,我需要使用 I/O multiplexing 來改善網頁伺服器的效能。在這之前必須要撰寫一個網頁伺服器來傳送指令給 qtest 這個執行檔。

$ ./qtest
cmd> web
listen on port 9999, fd is 3

當我們使用 web 這道指令時會輸出以上訊息。

$ curl 127.0.0.1:9999/new
l = []

同時我們只要再開啟一個終端機,並輸入 curl 傳送指令 new 給本地端,則會接收到回傳的訊息顯示我們建立了一個新的鍊結串列。

$ ./qtest
cmd> web
listen on port 9999, fd is 3
cmd> l = []

同時在原本的終端機上也可以發現印出了建立了新的鍊結串列的提示訊息。

cmd> l = []
cmd> Unknown command 'favicon.ico'

或我們使用網頁瀏覽器對本地端傳送 new 指令的話則會跑出 favicon.ico 的相關錯誤訊息。

char *buffer = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n";

理由是因為有些網頁瀏覽器會要求傳送圖形的對應資料,而我們的字串裡面並沒有包含這項資訊。

char *buffer = 
        "HTTP/1.1 200 OK\r\n%s%s%s%s%s%s"
        "Content-Type: text/html\r\n\r\n" "<html><head><style>"
        "body{font-family: monospace; font-size: 13px;}"
        "td {padding: 1.5px 6px;}"
        "</style><link rel=\"shortcut icon\" href=\"#\">"
        "</head><body><table>\n";
        web_send(web_connfd, buffer);

與此同時只要在 html 檔案裡面補上這些資料,就可以解決 favicon.ico 的問題。參考資料
到了這一步為止一個正常可以跟本地端溝通的網頁伺服器就產生了,接下來繼續進行 I/O 多工的相關改動。

接下來要理解 I/O 的各種處理方式的話,就必須要理解以下幾種同步處理方式,

  • blocking I/O
    • 又名阻塞式 I/O 當 user space 呼叫 read 系統呼叫時,kernel space 根據給定的 file descripter 複製一份資料給 user space 預先配置好的記憶體空間,在這過程之中 user space 只能夠等待 kernel 回傳資料。其中牽涉到 linux 的 everything is a file descripter 觀念,以及在 linux 中 kernel 以及 user 資料是完全獨立的特性。
  • Non blocking I/O
    • 與 blocking I/O 不同,每次都檢查資料使否已經準備好(可以通過檢查 EAGAIN),若還沒準備好的話 user space 可以先繼續做別的事情,當準備好的時候就透過 kernel 把資料傳回來,所以 blocking 以及 Non blocking 本質上是一種選擇,可以把 I/O 全程交給 kernel,也可以選擇不要,但要拿取資料這個操作終究都是要透過 kernel 操作。
  • I/O multiplexing
    • 透過 multiplexer 一次監控多個資料,只要一有風吹草動,就去馬上使用系統呼叫拿取資料,所以本質上還是 blocking,也就是 select / epoll 行為。

TODO: 強化亂數和相關統計描述

參見第六次作業
改進關於亂數的探討,強化統計相關原理,對照相關教科書描述。

TODO: 改進常數時間判定

參照 Linux 核心專題: 判定常數時間