Interrupt 線程與OS

基本思想

一個(gè)線程不應(yīng)該由其他線程來強(qiáng)制中斷或停止,而是應(yīng)該由線程自己自行停止娜氏。 中斷,只是一個(gè)協(xié)作通知信號(hào)量墩新。好比是家里的父母叮囑在外的子女要注意身體贸弥,但子女是否注意身體,怎么注意身體則完全取決于自己海渊。

  • 因之前的思想與現(xiàn)在的相悖绵疲,故Thread.stop, Thread.suspend, Thread.resume 都已經(jīng)被廢棄了哲鸳。
  • 現(xiàn)在的思想是采用Thread.interrupt ,其作用其實(shí)也不是中斷線程盔憨,而是「通知線程應(yīng)該中斷了」徙菠,具體到底中斷還是繼續(xù)運(yùn)行,應(yīng)該由被通知的線程自己處理郁岩。

具體來說婿奔,當(dāng)對(duì)一個(gè)線程,調(diào)用 interrupt() 時(shí)问慎,

  • 如果線程處于被阻塞狀態(tài)(例如處于sleep, wait, join 等狀態(tài))萍摊,那么線程將立即退出被阻塞狀態(tài),并拋出一個(gè)InterruptedException異常如叼。僅此而已冰木。
  • 如果線程處于正常活動(dòng)狀態(tài)笼恰,那么會(huì)將該線程的中斷標(biāo)志設(shè)置為 true踊沸,僅此而已。被設(shè)置中斷標(biāo)志的線程將繼續(xù)正常運(yùn)行挖腰,不受影響雕沿。

interrupt() 并不能真正的中斷線程,需要被調(diào)用的線程自己進(jìn)行配合才行猴仑。也就是說审轮,一個(gè)線程如果有被中斷的需求,那么就可以這樣做辽俗。

  • 在正常運(yùn)行任務(wù)時(shí)疾渣,經(jīng)常檢查本線程的中斷標(biāo)志位,如果被設(shè)置了中斷標(biāo)志就自行停止線程崖飘。
  • 在調(diào)用阻塞方法時(shí)正確處理InterruptedException異常榴捡。
    (例如,catch異常后就結(jié)束線程朱浴。)
  • 當(dāng)你的捕獲到一個(gè)InterruptedException異常后吊圾,亦可以處理它,或者向上拋出翰蠢。
  • 拋出時(shí)要注意:當(dāng)你捕獲到InterruptedException異常后项乒,當(dāng)前線程的中斷狀態(tài)已經(jīng)被修改為false(表示線程未被中斷);此時(shí)你若能夠處理中斷梁沧,則不用理會(huì)該值檀何;但如果你繼續(xù)向上拋InterruptedException異常,你需要再次調(diào)用interrupt方法,將當(dāng)前線程的中斷狀態(tài)設(shè)為true频鉴。
  • 注意:絕對(duì)不能“吞掉中斷”栓辜!即捕獲了InterruptedException而不作任何處理。這樣違背了中斷機(jī)制的規(guī)則垛孔,別人想讓你線程中斷藕甩,然而你自己不處理,也不將中斷請(qǐng)求告訴調(diào)用者周荐,調(diào)用者一直以為沒有中斷請(qǐng)求辛萍。

相關(guān)方法

方法 說明
public static boolean interrupted 測試當(dāng)前線程是否已經(jīng)中斷。線程的中斷狀態(tài) 由該方法清除羡藐。換句話說,如果連續(xù)兩次調(diào)用該方法悯许,則第二次調(diào)用將返回 false(在第一次調(diào)用已清除了其中斷狀態(tài)之后仆嗦,且第二次調(diào)用檢驗(yàn)完中斷狀態(tài)前,當(dāng)前線程再次中斷的情況除外)先壕。
public boolean isInterrupted() 測試線程是否已經(jīng)中斷瘩扼。線程的中斷狀態(tài)不受該方法的影響。
public void interrupt() 中斷線程垃僚。

Linux 中斷

什么是中斷集绰,操作系統(tǒng)級(jí)別的定義

Linux 內(nèi)核需要對(duì)連接到計(jì)算機(jī)上的所有硬件設(shè)備進(jìn)行管理,毫無疑問這是它的份內(nèi)事谆棺。如果要管理這些設(shè)備栽燕,首先得和它們互相通信才行,一般有兩種方案可實(shí)現(xiàn)這種功能:

  1. 輪詢(polling)** 讓內(nèi)核定期對(duì)設(shè)備的狀態(tài)進(jìn)行查詢改淑,然后做出相應(yīng)的處理碍岔;
  2. 中斷(interrupt)** 讓硬件在需要的時(shí)候向內(nèi)核發(fā)出信號(hào)(變內(nèi)核主動(dòng)為硬件主動(dòng))。

第一種方案會(huì)讓內(nèi)核做不少的無用功朵夏,因?yàn)檩喸兛倳?huì)周期性的重復(fù)執(zhí)行蔼啦,大量地耗用 CPU 時(shí)間,因此效率及其低下仰猖,所以一般都是采用第二種方案

從物理學(xué)的角度看捏肢,中斷是一種電信號(hào),由硬件設(shè)備產(chǎn)生饥侵,并直接送入中斷控制器(如 8259A)的輸入引腳上鸵赫,然后再由中斷控制器向處理器發(fā)送相應(yīng)的信號(hào)。處理器一經(jīng)檢測到該信號(hào)爆捞,便中斷自己當(dāng)前正在處理的工作奉瘤,轉(zhuǎn)而去處理中斷。此后,處理器會(huì)通知 OS 已經(jīng)產(chǎn)生中斷盗温。這樣藕赞,OS 就可以對(duì)這個(gè)中斷進(jìn)行適當(dāng)?shù)奶幚怼?strong>不同的設(shè)備對(duì)應(yīng)的中斷不同,而每個(gè)中斷都通過一個(gè)唯一的數(shù)字標(biāo)識(shí)卖局,這些值通常被稱為中斷請(qǐng)求線斧蜕。

一、最簡單的中斷機(jī)制

最簡單的中斷機(jī)制就是像芯片手冊(cè)上講的那樣砚偶,在中斷向量表中填入跳轉(zhuǎn)到對(duì)應(yīng)處理函數(shù)的指令批销,然后在處理函數(shù)中實(shí)現(xiàn)需要的功能。類似下圖:



這種方式在原來的單片機(jī)課程中常常用到染坯,一些簡單的單片機(jī)系統(tǒng)也是這樣用均芽。
它的好處很明顯,簡單单鹿,直接掀宋。

二、下半部:分離中斷接收與中斷處理過程

中斷處理函數(shù)所作的第一件事情是什么仲锄?答案是屏蔽中斷(或者是什么都不做劲妙,因?yàn)槌3J侨绻磺宄齀F位,就等于屏蔽中斷了)儒喊,當(dāng)然只屏蔽同一種中斷镣奋。之所以要屏蔽中斷,是因?yàn)樾碌闹袛鄷?huì)再次調(diào)用中斷處理函數(shù)怀愧,導(dǎo)致原來中斷處理現(xiàn)場的破壞侨颈。即,破壞了 interrupt context芯义。

隨著系統(tǒng)的不斷復(fù)雜肛搬,中斷處理函數(shù)要做的事情也越來越多,多到都來不及接收新的中斷了毕贼。于是發(fā)生了中斷丟失温赔,這顯然不行,于是產(chǎn)生了新的機(jī)制:分離中斷接收與中斷處理過程鬼癣。中斷接收在屏蔽中斷的情況下完成陶贼;中斷處理在使能中斷的情況下完成,這部分被稱為中斷下半部待秃。



從上圖中看拜秧,只看int0的處理。Func0為中斷接收函數(shù)章郁。中斷只能簡單的觸發(fā)func0枉氮,而func0則能做更多的事情志衍,它與funcA之間可以使用隊(duì)列等緩存機(jī)制。當(dāng)又有中斷發(fā)生時(shí)聊替,func0被觸發(fā)楼肪,然后發(fā)送一個(gè)中斷請(qǐng)求到緩存隊(duì)列,然后讓funcA去處理惹悄。

由于func0做的事情是很簡單的春叫,所以不會(huì)影響int0的再次接收。而且在func0返回時(shí)就會(huì)使能int0泣港,因此funcA執(zhí)行時(shí)間再長也不會(huì)影響int0的接收暂殖。

三、軟中斷(統(tǒng)一調(diào)度器)

下面看看linux中斷處理当纱。作為一個(gè)操作系統(tǒng)顯然不能任由每個(gè)中斷都各自為政呛每,統(tǒng)一管理是必須的。

我們不可中斷部分的共同部分放在函數(shù)do_IRQ中坡氯,需要添加中斷處理函數(shù)時(shí)莉给,通過request_irq實(shí)現(xiàn)。下半部放在do_softirq中廉沮,也就是軟中斷,通過open_softirq添加對(duì)應(yīng)的處理函數(shù)徐矩。


四滞时、tasklet

舊事物跟不上歷史的發(fā)展時(shí),總會(huì)有新事物出現(xiàn)滤灯。

隨著中斷數(shù)的不停增加坪稽,軟中斷不夠用了,于是下半部又做了進(jìn)化鳞骤。

軟中斷用輪詢的方式處理窒百。假如正好是最后一種中斷,則必須循環(huán)完所有的中斷類型豫尽,才能最終執(zhí)行對(duì)應(yīng)的處理函數(shù)篙梢。顯然當(dāng)年開發(fā)人員為了保證輪詢的效率,于是限制中斷個(gè)數(shù)為32個(gè)美旧。

為了提高中斷處理數(shù)量渤滞,順道改進(jìn)處理效率,于是產(chǎn)生了tasklet機(jī)制榴嗅。

Tasklet采用無差別的隊(duì)列機(jī)制妄呕,有中斷時(shí)才執(zhí)行,免去了循環(huán)查表之苦嗽测。


總結(jié)下tasklet的優(yōu)點(diǎn):

(1)無類型數(shù)量限制绪励;
(2)效率高,無需循環(huán)查表;
(3)支持SMP機(jī)制疏魏;

五停做、工作隊(duì)列

前面的機(jī)制不論如何折騰,有一點(diǎn)是不會(huì)變的蠢护。它們都在中斷上下文中雅宾。什么意思?說明它們不可掛起葵硕。而且由于是串行執(zhí)行眉抬,因此只要有一個(gè)處理時(shí)間較長,則會(huì)導(dǎo)致其他中斷響應(yīng)的延遲懈凹。為了完成這些不可能完成的任務(wù)蜀变,于是出現(xiàn)了工作隊(duì)列。工作隊(duì)列說白了就是一組內(nèi)核線程介评,作為中斷守護(hù)線程來使用库北。多個(gè)中斷可以放在一個(gè)線程中,也可以每個(gè)中斷分配一個(gè)線程们陆。

工作隊(duì)列對(duì)線程作了封裝寒瓦,使用起來更方便。

因?yàn)楣ぷ麝?duì)列是線程坪仇,所以我們可以使用所有可以在線程中使用的方法杂腰。

Tasklet其實(shí)也不一定是在中斷上下文中執(zhí)行,它也有可能在線程中執(zhí)行椅文。

假如中斷數(shù)量很多喂很,而且這些中斷都是自啟動(dòng)型的(中斷處理函數(shù)會(huì)導(dǎo)致新的中斷產(chǎn)生),則有可能cpu一直在這里執(zhí)行中斷處理函數(shù)皆刺,會(huì)導(dǎo)致用戶進(jìn)程永遠(yuǎn)得不到調(diào)度時(shí)間少辣。

為了避免這種情況,linux發(fā)現(xiàn)中斷數(shù)量過多時(shí)羡蛾,會(huì)把多余的中斷處理放到一個(gè)單獨(dú)的線程中去做漓帅,就是ksoftirqd線程。這樣又保證了中斷不多時(shí)的響應(yīng)速度痴怨,又保證了中斷過多時(shí)不會(huì)把用戶進(jìn)程餓死煎殷。

問題是我們不能保證我們的tasklet或軟中斷處理函數(shù)一定會(huì)在線程中執(zhí)行,所以還是不能使用進(jìn)程才能用的一些方法腿箩,如放棄調(diào)度豪直、長延時(shí)等。

Tasklet機(jī)制分析

有了軟中斷珠移,linux內(nèi)核為什么要引入tasklet機(jī)制呢弓乙?主要原因:

  • 軟中斷的pending標(biāo)志位也就32位末融,一般情況是不隨意增加軟中斷處理的。
  • 內(nèi)核沒有提供通用的增加軟中斷的接口暇韧。
  • 軟中斷處理函數(shù)要求可重入勾习,需要考慮到競爭條件比較多,要求比較高的編程技巧懈玻。所以內(nèi)核提供了tasklet這樣的一種通用的機(jī)制巧婶。

把細(xì)節(jié)的東西說明白,會(huì)越寫越多涂乌。這樣做的好處是能真正理解其中的機(jī)制艺栈。但是,內(nèi)容太多的一個(gè)壞處就是難道記憶湾盒。所以先把精髓總結(jié)出來湿右。Tasklet的特點(diǎn),也是tasklet的精髓就是:

  • tasklet不能休眠
  • 同一個(gè)tasklet不能在兩個(gè)CPU上同時(shí)運(yùn)行
  • 不同tasklet可能在不同CPU上同時(shí)運(yùn)行
  • 需要注意共享數(shù)據(jù)的保護(hù)罚勾。

軟中斷和tasklet的總結(jié)

  • 軟中斷:

1毅人、軟中斷是在編譯期間靜態(tài)分配的。
2尖殃、最多可以有32個(gè)軟中斷丈莺。
3、軟中斷不會(huì)搶占另外一個(gè)軟中斷送丰,唯一可以搶占軟中斷的是中斷處理程序缔俄。
4、可以并發(fā)運(yùn)行在多個(gè)CPU上(即使同一類型的也可以)蚪战。所以軟中斷必須設(shè)計(jì)為可重入的函數(shù)(允許多個(gè)CPU同時(shí)操作),因此也需要使用自旋鎖來保護(hù)其數(shù)據(jù)結(jié)構(gòu)铐懊。
5邀桑、目前只有兩個(gè)子系直接使用軟中斷:網(wǎng)絡(luò)和SCSI。
6科乎、執(zhí)行時(shí)間有:從硬件中斷代碼返回時(shí)壁畸、在ksoftirqd內(nèi)核線程中和某些顯示檢查并執(zhí)行軟中斷的代碼中。

  • tasklet:

1茅茂、tasklet是使用兩類軟中斷實(shí)現(xiàn)的:HI_SOFTIRQ和TASKLET_SOFTIRQ捏萍。本質(zhì)上沒有什么區(qū)別,只不過HI_SOFTIRQ的優(yōu)先級(jí)更高一些空闲,建立在HI_SOFTIRQ上的tasklet會(huì)早于TASKLET_SOFTIRQ執(zhí)行令杈。
2、可以動(dòng)態(tài)增加減少碴倾,沒有數(shù)量限制逗噩。
3掉丽、同一類的tasklet不能并發(fā)執(zhí)行。
4异雁、不同類的tasklet可以并發(fā)執(zhí)行捶障。
5、大部分情況下推薦使用tasklet纲刀。

Ref:
https://www.zhihu.com/question/41048032
http://www.infoq.com/cn/articles/java-interrupt-mechanism
https://www.ibm.com/developerworks/cn/linux/l-cn-linuxkernelint/index.html
http://blog.jobbole.com/105524/
http://unicornx.github.io/2016/02/12/20160212-lk-drv-tasklet/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末项炼,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子示绊,更是在濱河造成了極大的恐慌锭部,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,084評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件耻台,死亡現(xiàn)場離奇詭異空免,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)盆耽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門蹋砚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人摄杂,你說我怎么就攤上這事坝咐。” “怎么了析恢?”我有些...
    開封第一講書人閱讀 163,450評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵墨坚,是天一觀的道長。 經(jīng)常有香客問我映挂,道長泽篮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,322評(píng)論 1 293
  • 正文 為了忘掉前任柑船,我火速辦了婚禮帽撑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘鞍时。我一直安慰自己亏拉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評(píng)論 6 390
  • 文/花漫 我一把揭開白布逆巍。 她就那樣靜靜地躺著及塘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪锐极。 梳的紋絲不亂的頭發(fā)上笙僚,一...
    開封第一講書人閱讀 51,274評(píng)論 1 300
  • 那天,我揣著相機(jī)與錄音灵再,去河邊找鬼味咳。 笑死庇勃,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的槽驶。 我是一名探鬼主播责嚷,決...
    沈念sama閱讀 40,126評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼掂铐!你這毒婦竟也來了罕拂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,980評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤全陨,失蹤者是張志新(化名)和其女友劉穎爆班,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體辱姨,經(jīng)...
    沈念sama閱讀 45,414評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡柿菩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了雨涛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片枢舶。...
    茶點(diǎn)故事閱讀 39,773評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖替久,靈堂內(nèi)的尸體忽然破棺而出凉泄,到底是詐尸還是另有隱情,我是刑警寧澤蚯根,帶...
    沈念sama閱讀 35,470評(píng)論 5 344
  • 正文 年R本政府宣布后众,位于F島的核電站,受9級(jí)特大地震影響颅拦,放射性物質(zhì)發(fā)生泄漏蒂誉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評(píng)論 3 327
  • 文/蒙蒙 一距帅、第九天 我趴在偏房一處隱蔽的房頂上張望右锨。 院中可真熱鬧,春花似錦锥债、人聲如沸陡蝇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至广匙,卻和暖如春允趟,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鸦致。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評(píng)論 1 269
  • 我被黑心中介騙來泰國打工潮剪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涣楷,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,865評(píng)論 2 370
  • 正文 我出身青樓抗碰,卻偏偏與公主長得像狮斗,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子弧蝇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容