中断处理过程示意图_聊聊什么是中断机制?
什么是中斷
中斷其實是一種“中斷”事件,中斷具體代表什么意思需要考慮它所處的上下文環(huán)境和參照對象是誰??紤]事件,我們可以簡單把中斷抽象為這樣一種模型:
當我們分析某種中斷事件時,我們需要搞清楚這四個對象:
中斷源
- 中斷源是誰
- 中斷源在什么條件下觸發(fā)中斷
- 中斷源如何觸發(fā)
中斷信號
- 信號具體指的是什么
- 信號是否需要存儲
- 如何存儲
中斷控制器
- 中斷信號的管理
比如說中斷源發(fā)送的信號是否屏蔽,信號是否可被中斷處理器重復處理,信號的處理是否有優(yōu)先級...
中斷處理器
- 如何獲取到信號
- 拿到信號做什么樣的操作
- 處理完信號后做什么樣的操作
在實際的中斷事件中,并不一定剛好有上面提到的這四類對象,可能更復雜可能更簡單化。但是當我們考慮中斷事件時,需要明確應該有類似功能的“對象”承擔這樣的邏輯。
下面我們主要圍繞操作系統(tǒng)的中斷機制,Java的中斷機制,如何設計一個異步線程間的中斷系統(tǒng)這三部分簡單探討下。
操作系統(tǒng)的中斷機制
與操作系統(tǒng)有關的中斷,通常是指:程序在執(zhí)行過程中,遇到急需處理的事件時,暫時中止CPU上現(xiàn)行程序的運行, 轉去執(zhí)行相應的事件處理程序,待處理完成 后再返回原程序被中斷處或調度其他程序執(zhí)行的過程。
按照中斷事件本身的不同,可以劃分為處理器之外的中斷事件,異常,系統(tǒng)異常。
處理器之外的中斷事件
指由外圍設備發(fā)出的信號引起的,與當前運行指令無關的中斷事件。示意圖如下:
我們分別以上述四個對象來看:
- 中斷源
中斷源:外部設備,如打印機,鍵盤,鼠標等。
觸發(fā)條件:如外圍設備報告I/O狀態(tài)的I/O中斷;外圍設備發(fā)出的對應信號中斷,如時鐘中斷,鍵盤/鼠標對應信號的中斷,關機/重啟動中斷等。
觸發(fā)方式:由外部設備向中斷控制器發(fā)出中斷請求IRQ。
- 中斷信號
也就是說中斷源通知給中斷控制器的是什么。
可以是通過一條信號線上產(chǎn)生特定的電平(利用高低電平表示是否中斷兩種狀態(tài)),也可以在總線上發(fā)送特定消息或者消息序列,也可以是在中斷寄存器中設置已發(fā)生的中斷狀態(tài)等。
- 中斷控制器
CPU中的一個控制部件,包括 中斷控制邏輯線路和中斷寄存器。負責中斷的發(fā)現(xiàn)和響應。
也就是說負責檢查中斷寄存器中的中斷信號,當發(fā)現(xiàn)中斷時讓CPU切換當前進程程序,去處理中斷程序。響應示意圖如下:
- 中斷處理器
指的是CPU接收到不同的中斷信號該怎么處理。包括“中斷處理過程”和“恢復正常操作”兩部分。
1.中斷處理過程
首先CPU需要將當前運行進程的上下文保存,從中斷進程中分析PSW,確定對應的中斷源和執(zhí)行對應的中斷處理程序。
小貼士:PSW(Program Status Word): 是指在電腦中,一段包含被操作系統(tǒng)使用的程序狀態(tài)信息的內(nèi)存或硬件區(qū)域。一般用一個專門的寄存器來指示處理器狀態(tài)??梢岳斫鉃槲覀兩厦嫣岬降闹袛嘈盘柎鎯ρb置.
2.恢復正常操作
當中斷程序執(zhí)行完畢,接下來執(zhí)行哪個進程由進程調度決定,由調度策略決定是否調度到中斷執(zhí)行前的進程。
較為完整的中斷響應流程圖如下:
異常 和 系統(tǒng)異常 這兩類中斷事件主要屬于處理器執(zhí)行特定的指令引起的中斷事件。和上述硬件外圍設備引起的中斷事件的中斷源不同,中斷的發(fā)起,控制和處理主要是由操作系統(tǒng)的指令邏輯和線路來承擔。是一種同步的處理操作,而外部中斷是由外部設備發(fā)起,是一種異步的處理操作。下面我們簡要介紹下。
異常
異常指當前運行指令引起的中斷事件。包括錯誤情況引起的故障,如除零算數(shù)錯誤,缺頁異常;也包括不可恢復的致命錯誤導致的終止,通常是一些硬件錯誤。
- 異常的處理
對于故障的處理,根據(jù)故障是否能夠被恢復,故障處理程序要么重新執(zhí)行引起故障的指令,要么終止。
對于終止的處理,處理程序將控制返回給一個abort例程,該例程會終止這個應用程序。
系統(tǒng)異常
系統(tǒng)異常指執(zhí)行陷入指令而觸發(fā)系統(tǒng)調用引起的中斷事件,如請求設備、請求I/O、創(chuàng)建進程等。
- 系統(tǒng)調用的處理
這種有意的異常,稱為陷阱處理。處理完成后陷阱程序會將控制返回給應用程序控制流的下一條指令。
總結一下,操作系統(tǒng)的中斷類別行為如下:
好了,大頭總算完了。因為小姐姐主要是Java碼農(nóng),下面將主要介紹和Java相關的中斷語義是什么。
Java的中斷機制
理解了上面操作系統(tǒng)的中斷之后,Java的中斷機制就很easy了 :D
Java中斷指的是 A線程發(fā)送中斷信號給B線程,B線程再根據(jù)自己當前執(zhí)行程序中的中斷處理邏輯決定如何響應。嗯,就這么簡單~
我們來稍微分析一下中斷事件中的“四個對象”:
- 中斷源
中斷源:A線程
中斷觸發(fā)條件:A線程說了算
中斷源觸發(fā)方式:A線程中調用threadB#interrupt()方法.
實現(xiàn)機制也不難,扯淡之前我們先思考兩個問題:
問:
問題1: 線程之間如何通信,A線程的中斷信號怎么才能傳給線程B?
問題2: 線程的狀態(tài)有Running,Blocked,Waiting等,當線程B處在不同的狀態(tài)下,如何響應中斷信號?
答:
問題1:這種情況下線程之間通信用共享內(nèi)存就可以了。只需要給每個線程都設置一個中斷標示位, 這樣A線程中調用threadB#interrupt()方法,實際操作是把B線程的中斷標示位設置為true。信號就算傳遞過去了
問題2:當B線程處于非阻塞狀態(tài)時,B線程可以在自己需要處理中斷邏輯的地方判斷中斷標示位是否為true,就可以響應處理中斷。
但是當B線程處于阻塞狀態(tài)時,這特么怎么查自己的中斷標示位啊?
JVM幫幫忙,當B線程阻塞在Object#wait(),Thread#join(),Thread#sleep(),實現(xiàn)了InterruptibleChannel接口的IO操作 和Selector接口的select()這些操作時,JVM會讓B線程馬上拋出異常或被喚醒,從而讓B線程可以選擇是否響應中斷。
因為是Java實現(xiàn)的中斷機制,中斷標示位的設置也是JVM幫做的。
- 中斷信號
信號:線程的中斷標示位。
存儲方式:JVM說了算。
- 中斷控制器
JVM控制了信號的存儲和讓線程B及時喚醒。線程B控制了自己的中斷響應邏輯,何時響應,如何響應。
- 中斷處理器
獲取信號:B線程可通過調用threadB#isInterrupted()方法得知自己是否被中斷,也就是通過自己主動拉取信號(poll方式)。
如何處理信號:B線程說了算。
處理完信號后做什么:B線程說了算。
Java的線程中斷機制設計的比較靈活,使用者可以決定中斷處理的較多事情。
總結下Java中和中斷有關的方法:
在JDK中,線程池的ThreadPoolExecutor#shutdownNow()方法就是調用workers線程數(shù)組中每個worker線程的interrupt()方法來關閉線程池。
這樣暴力關閉線程會存在一個問題,線程池并不知道worker線程的中斷執(zhí)行情況,如果worker線程忽略了中斷信號,那可能導致當前任務還在執(zhí)行,發(fā)生意想不到的結果。
設計一個異步線程間的中斷系統(tǒng)
我們再來看Java的中斷機制,它其實只是提供了A線程給B線程發(fā)送中斷信號。
- A線程并不能知道B線程的中斷處理結果。
- 如果A線程拿不到B線程的thread對象時,也就沒法發(fā)送中斷信號。
考慮這么一種場景:當我們執(zhí)行一個大任務Task1時,它太大了。我們把它分為Task2和Task3,丟進線程池中處理。它們同樣很大,我們把他們分別分為Task4,Task5和Task6,Task7,同樣丟進線程池中處理。
如果此時我們想取消task1的執(zhí)行,如何保證圖中所有的worker都成功取消對應task的執(zhí)行?
- 需求分析
當我們?nèi)∠鹴ask1時,想要做的是取消所有task程序的繼續(xù)運行,并且能夠獲得所有task程序的取消結果。
為什么要強調task程序呢?因為worker可能并不是只為一個task工作啊..比如task2的worker,它把task4和task5丟進線程池,就算完事了。如果我們把取消task1變?yōu)槿∠鹴ask1的worker線程,可能會導致worker線程當前運行的非task1程序的失敗。
我們不太容易知道所有task程序當前運行的線程,我們還需要知道所有task程序的運行結果。
- 設計思路
只用Java的中斷機制是滿足不了我們的需求的,但是我們可以借鑒它的思路:
1.它用中斷標示位記錄線程是否應該中斷
2.當線程阻塞時可以拋出異常
我們這里要終止的是所有task程序的執(zhí)行,所以我們需要設計與task 強綁定的中斷標示位,可以有未中斷,中斷中,中斷成功,中斷失敗四種 狀態(tài)。為了讓所有的線程都可以訪問到,定義成全局共享變量就可以。
中斷源和中斷處理器之間通過task的中斷標示位來通信就可以。如果運行task程序的線程一直在阻塞,怎么喚醒它讓它判斷中斷狀態(tài) 呢?
對于我們這個場景,我們很難知道當前運行task程序的阻塞線程是誰。。能做的只是多安插中斷判斷點,這樣當阻塞線程醒來后,再次判斷task 的中斷標示位,就可以響應中斷了。
另:
喚醒一個線程只有Java的中斷機制可以做,但是如果當前worker不是你能管理的線程池,那么它的中斷處理邏輯就控制不了。
如果你能控制運行task的所有worker,而且worker在執(zhí)行task時是同步獲得結果的。那么可以結合與task強綁定的中斷標示位和Java中斷機制來做,這里前者的作用更多是充當獲取到任務的中斷結果的作用。
后記
- 小姐姐覺得像是“事件處理”這種場景在線程池,消息中間件,流式處理等很多地方有共通之處,比如說:如何保證事件的exactly once,推拉模型,調度等等。
- 在寫這篇文章時,特別是操作系統(tǒng)的中斷機制,小姐姐也是現(xiàn)學現(xiàn)賣,并且參考了資料大部分內(nèi)容。文章中有理解錯誤或者難懂的地方還請小伙伴幫我指出,一起交流進步。
- 最后的技術部分討論“如何設計一個異步線程間的中斷系統(tǒng)”,這是小姐姐目前工作中遇到的一個問題。這個問題和任務調度組件的取消任務很相似,只是我們目前還沒有用任務調度組件管理起所有的任務工作線程。小伙伴有更好方案的也請告知小姐姐。
總結
以上是生活随笔為你收集整理的中断处理过程示意图_聊聊什么是中断机制?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 恋与制作人羁绊升星(汉典恋字的基本解释)
- 下一篇: 普通电视怎么连接小爱(什么是普通人)