成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

操作系統是如何一步步發明中斷機制的?

系統 其他OS
現在CPU不再需要一遍遍檢查設備狀態而是可以專注于執行正常任務的機器指令,當外部設備需要CPU關注時發起中斷信號,然后CPU將跳轉到提前定義好的中斷處理函數去執行。
1960年代初期,你正在開發一個批處理系統,用于自動化處理大量的數據任務。

系統需要頻繁地與磁帶機和打印機等外部設備交互。然而,這些設備的響應速度遠遠低于CPU的處理速度。例如,磁帶機讀取一個數據塊需要約100毫秒,而打印機打印一行數據更是需要超過600毫秒。

在等待設備響應的過程中,CPU只能不斷地查詢設備狀態,就像這樣:

int poll_count = 0;

// 輪詢等待打印機就緒
while (1) {
    poll_count++;
    if (check_printer_status() == PRINTER_READY) {
        send_to_printer(print_data);
        break;
    }
}

這就是所謂輪詢,這個示例程序通過不斷輪詢打印機狀態來等待設備就緒,只要打印機不READY你就沒有辦法跳出這個while循環,這導致大量的計算資源被浪費。

靈感時刻

1954年IBM 704的出現給了你靈感,因為這臺機器上出現了一種有趣的特性。

圖片

IBM 704 具有一個溢出標志位(Overflow Flag, OV),它會在某些算術運算(如加法、乘法等)導致溢出時被設置,程序員可以手動檢查這個標志位,并根據需要進行錯誤處理:

ADD MQ        // AC = AC + MQ,可能導致溢出
   TOV ERROR     // 如果 OV 標志為 1,則跳轉到 ERROR 處理異常
   TRA CONTINUE  // 否則繼續執行程序

ERROR 
   // 錯誤處理指令
CONTINUE
   // 繼續執行其他指令

圖片 圖片 你看到后想了一下,為什么要程序員自己手寫匯編來檢查異常呢,實現在CPU硬件層面就好了,出現A錯誤就跳轉到X代碼,出現B錯誤就跳轉到Y代碼等等,這樣程序員只需要編寫正常的處理邏輯就好。

以程序除0錯誤為例:

void test_division() {
    int a = 10;
    int b = 0;  // 除數為零
    int result = a / b;  // CPU立即觸發異常處理
    // 這行代碼永遠不會執行
    printf("結果是: %d\n", result);
}

當CPU執行到除法操作時,它能夠立即檢測到除數為零的情況,并自動跳轉到異常處理程序(提前定義好的),而不是等待程序員自己檢查除數是否為零。

中斷的發明

這種機制給你帶了新的啟示:實際上這相當于軟件出現異常后可以通知CPU去執行一段異常處理邏輯,而且整個過程非常絲滑,因為異常處理邏輯是提前定義好的,CPU能根據異常類型去執行不同的異常處理邏輯。

到這里你靈光乍現,既然軟件能通知CPU那么外部設備顯然也可以通知CPU。

圖片圖片

可以把上述機制應用在外部設備上,為此你進行了如下設計:

  1. 硬件層面:外部設備通過特定的信號線連接到CPU
  2. 信號觸發:設備就緒時產生電平變化
  3. CPU響應:檢測到信號后立即切換到處理程序
  4. 任務恢復:處理完成后返回原程序繼續執行

這種設計可以讓CPU不再需要主動查詢設備狀態,而是由設備在就緒時主動通知CPU,從而大大減少了CPU資源的浪費,到這里你發明了中斷機制。

圖片圖片

中斷的實現

現在CPU不但能響應軟件異常也能響應外部設備,這些統統被稱為中斷。

只不過來自軟件的就被稱為軟中斷,比如除零錯誤、內存訪問違規、系統調用等;來自硬件的就被稱之為硬中斷,比如I/O設備中斷(如打印機、磁盤完成操作)、時鐘中斷等。

你在自己實現的內核中定義了這些中斷類型:

// 中斷類型定義
typedefenum {
    // 硬件中斷
    INT_PRINTER = 0,    // 打印機中斷
    INT_DISK = 1,       // 磁盤中斷
    INT_TIMER = 2,      // 時鐘中斷
    INT_KEYBOARD = 3,   // 鍵盤中斷
    
    // 軟件中斷
    INT_DIVIDE_BY_ZERO = 4,    // 除零錯誤
    INT_PAGE_FAULT = 5,        // 頁面錯誤
    INT_SYSTEM_CALL = 6,       // 系統調用
    
    MAX_INTERRUPT_TYPE = 7
} InterruptType;

除此之外你還需要實現中斷處理函數,中斷處理函數應該能處理所有類型的中斷,其本質就是一個函數數組,你將其命名為中斷向量表:

// 中斷處理函數的類型定義
typedef void (*InterruptHandler)(void);

// 中斷向量表結構
typedef struct {
    InterruptHandler handlers[MAX_INTERRUPT_TYPE];
    bool enabled[MAX_INTERRUPT_TYPE];        // 中斷使能狀態
} InterruptVectorTable;

從其定義可以看到:

  • 中斷向量表是一個存儲中斷號與對應中斷處理程序入口地址映射的表格。
  • 每個中斷號對應一個特定的事件(如硬件中斷、系統調用、異常等),中斷向量表中的每個條目通常包含:中斷處理程序的入口地址、可能還包括其他信息(如中斷優先級、狀態標志等)。

當發生中斷時,CPU使用中斷號作為索引,查找中斷向量表中的對應條目,從而獲取中斷處理程序的入口地址,其本質就是:

void handle_interrupt(InterruptVectorTable* ivt, InterruptType type) {
  ...
  ivt->handlers[type]();
  ...
}

現在CPU不再需要一遍遍檢查設備狀態而是可以專注于執行正常任務的機器指令,當外部設備需要CPU關注時發起中斷信號,然后CPU將跳轉到提前定義好的中斷處理函數去執行。

現在你應該對操作系統的中斷機制有所了解了吧。

責任編輯:武曉燕 來源: 碼農的荒島求生
相關推薦

2025-04-03 01:45:00

2025-04-30 04:20:00

操作系統虛擬內存

2024-09-30 09:56:59

2024-11-11 10:28:33

操作系統Unix系統

2024-09-12 10:04:06

內存程序系統

2025-04-09 08:45:00

操作系統進程線程

2018-07-13 15:36:52

2024-08-30 08:30:29

CPU操作系統寄存器

2017-01-19 21:08:33

iOS路由構建

2017-12-25 11:50:57

LinuxArch Linux

2024-08-06 09:29:54

程序機器指令字符串

2019-03-05 14:09:27

Docker存儲容器

2019-07-09 15:23:22

Docker存儲驅動

2018-12-24 10:04:06

Docker存儲驅動

2019-04-01 10:15:02

2010-03-04 16:28:17

Android核心代碼

2016-11-02 18:54:01

javascript

2017-01-06 15:13:25

LinuxVim源代碼

2015-07-27 16:06:16

VMware Thin虛擬化

2024-06-27 08:30:36

內存擴容堆區
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美视频二区 | 国产精品观看 | 久久久一二三 | 99在线资源 | 久久精品国产一区二区电影 | 成年人在线观看视频 | 精品一区精品二区 | av影音资源 | 少妇av片 | 黄色在线观看网站 | 久久影院一区 | 伊人最新网址 | 久久视频免费观看 | 久久专区 | 免费视频一区 | 日本精品久久 | 成人做爰www免费看视频网站 | 色姑娘av | 国产精品美女一区二区 | 日本免费视频 | 99精品欧美一区二区蜜桃免费 | 午夜影院中文字幕 | 日韩欧美在线视频一区 | 国产一级片一区二区三区 | 一区精品国产欧美在线 | 在线天堂免费中文字幕视频 | 北条麻妃一区二区三区在线视频 | 亚洲一二三区在线观看 | 精品啪啪 | 日本精品一区二区三区视频 | 精品国产网 | 久久99精品久久久久婷婷 | 视频二区在线观看 | 搞av.com| 午夜视频在线观看网址 | 国产一区二区三区四区在线观看 | 亚洲最色网站 | 精品国产欧美 | 91视频在线观看 | 黄色av大片| 三级成人片 |