當前位置:首頁 » 操作系統 » linux中斷機制

linux中斷機制

發布時間: 2022-04-13 04:08:21

linux中斷處理程序的方法

中斷程序處理,使用kill或killall命令後面加上程序ID號(pid)或者程序名。查看程序ID使用ps 命令,然後,再用kill -9 <pid> 回車就可以把指定的程序中斷了。再使用ps命令查看一下,原來的那個程序就沒有了。

如果有多個名字相同的程序你想中斷的話,就使用killall命令來指定程序名稱,就可以中斷多個相同名稱的程序了。格式如下:
killall -9 httpd
我這里以中斷httpd程序為例子。這樣也可以中斷程序執行。

❷ Linux幾種中斷信號的區別:HUP,INT,KILL,TERM,TSTP

Linux的HUP,INT,KILL,TERM,TSTP中斷信號區別為:鍵入不同、對應操作不同、啟用不同。

一、鍵入不同

1、HUP中斷信號:HUP中斷信號是當用戶鍵入<Ctrl+X>時由終端驅動程序發送的信號。

2、INT中斷信號:INT中斷信號是當用戶鍵入<Ctrl+I>時由終端驅動程序發送的信號。

3、KILL中斷信號:KILL中斷信號是當用戶鍵入<Ctrl+Z>時由終端驅動程序發送的信號。

4、TERM中斷信號:TERM中斷信號是當用戶鍵入<Ctrl+>時由終端驅動程序發送的信號。

5、TSTP中斷信號:TSTP中斷信號是當用戶鍵入<Ctrl+T>時由終端驅動程序發送的信號。二、對應操作不同

1、HUP中斷信號:HUP中斷信號的對應操作為讓進程掛起,睡眠。

2、INT中斷信號:INT中斷信號的對應操作為正常關閉所有進程。

3、KILL中斷信號:KILL中斷信號的對應操作為強制關閉所有進程。

4、TERM中斷信號:TERM中斷信號的對應操作為正常的退出進程。

5、TSTP中斷信號:TSTP中斷信號的對應操作為暫時停用進程。

三、啟用不同

1、HUP中斷信號:HUP中斷信號發送後,可以重新被用戶再次輸入恢復啟用進程。

2、INT中斷信號:INT中斷信號發送後,不可以重新被用戶再次輸入恢復啟用進程。

3、KILL中斷信號:KILL中斷信號發送後,不可以重新被用戶再次輸入恢復啟用進程。

4、TERM中斷信號:TERM中斷信號發送後,可以重新被用戶再次輸入啟用進程。

5、TSTP中斷信號:TSTP中斷信號發送後,可以重新被用戶再次輸入繼續使用進程。

❸ Linux如何及時響應外部中斷

FPGA每隔100us給運行linux的ARM一個中斷,要求在20us內響應中斷,並讀走2000*16bit的數據。
目前主要的問題是,當系統同時發生多個中斷時,會嚴重影響linux對FPGA中斷的響應時間。如何解決?

1、首先想到了ARM的FIQ,它可以打斷IRQ中斷服務程序,保證對外部FIQ的及時響應。但是發現linux只實現了IRQ,沒有顯示FIQ。
linux是從devicetree讀取中斷號,加入中斷向量表的。

interrupts = <0x0 0x32 0x0>;中的第一個欄位0表示非共享中斷,非零表示共享中斷,SDK產生的dts統一為0,此時第二欄位的值比XPS中的小32;如果第一欄位非零,則第二欄位比XPS小16.
最後欄位表示中斷的觸發方式。
IRQ_TYPE_EDGE_RISING =0x00000001,
IRQ_TYPE_EDGE_FALLING =0x00000002,
IRQ_TYPE_LEVEL_HIGH =0x00000004,
IRQ_TYPE_LEVEL_LOW =0x00000008,
很明顯,devicetree根本沒有提供通知linux有FIQ的渠道。
2、再來看linux的IRQ
linux的中斷分為上半部和下半部,上半部運行在IRQ模式,會屏蔽所有中斷,下半部運行在SVC模式,會重新打開中斷。
也就是說,當一個中斷的上半部正在運行時(不能再次響應中斷),FPGA的中斷是不能被linux響應的;
反過來,當FPGA中斷的上半部正在運行時(不能再次響應中斷),其他的中斷也不能被linux響應;
unsigned long flags;
...
local_irq_save(flags);
....

local_irq_restore(flags);

3.
ARM有七種模式,我們這里只討論SVC、IRQ和FIQ模式。
我們可以假設ARM核心有兩根中斷引腳(實際上是看不見的),一根叫 irq pin, 一根叫fiq pin.
在ARM的cpsr中,有一個I位和一個F位,分別用來禁止IRQ和FIQ的。
先不說中斷控制器,只說ARM核心。正常情況下,ARM核都只是機械地隨著pc的指示去做事情,當CPSR中的I和F位為1的時候,IRQ和FIQ全部處於禁止狀態。無論你在irq
pin和fiq pin上面發什麼樣的中斷信號,ARM是不會理你的,你根本不能打斷他,因為他耳聾了,眼也瞎了。
在I位和F位為0的時候,當irq
pin上有中斷信號過來的時候,就會打斷arm的當前工作,並且切換到IRQ模式下,並且跳到相應的異常向量表(vector)位置去執行代碼。這個過程是自動的,但是返回到被中斷打斷的地方就得您親自動手了。當你跳到異常向量表,處於IRQ的模式的時候,這個時候如果irq
pin上面又來中斷信號了,這個時候ARM不會理你的,irq
pin就跟秘書一樣,ARM核心就像老闆,老闆本來在做事,結果來了一個客戶,秘書打斷它,讓客戶進去了。而這個時候再來一個客戶,要麼秘書不斷去敲門問,要麼客戶走人。老闆第一個客戶沒有會見完,是不會理你的。
但是有一種情況例外,當ARM處在IRQ模式,這個時候fiq pin來了一個中斷信號,fiq
pin是什麼?是快速中斷呀,比如是公安局的來查刑事案件,那才不管你老闆是不是在會見客戶,直接打斷,進入到fiq模式下,並且跳到相應的fiq的異常向量表處去執行代碼。那如果當ARM處理FIQ模式,fiq
pin又來中斷信號,又就是又一批公安來了,那沒戲,都是執法人員,你打不斷我。那如果這個時候irq
pin來了呢?來了也不理呀,正在辦案,還敢來妨礙公務。
所以得出一個結論: IRQ模式只能被FIQ模式打斷,FIQ模式下誰也打不斷。
在打不斷的情況下,irq pin 或 fiq pin隨便你怎麼發中斷信號,都是白發。
所以除了fiq能打斷irq以外,根本沒有所謂中斷嵌套的情況。
Linux不用FIQ,只用到了IRQ。但是我們有時候一個中斷需要處理很長時間,那我們就需要佔用IRQ模式那麼長的時間嗎?沒有,linux在IRQ模式下只是簡單的記錄是什麼中斷,馬上就切換回了SVC模式,換句話說,Linux的中斷處理都是在SVC模式下處理的。
只不過SVC模式下的ISR上半部關閉了當前中斷線,下半部才重新打開

❹ linux中斷的問題

不會阻塞中斷處理函數,因為disable_irq_nosync只是屏蔽中斷觸發,而不是屏蔽中斷處理函數,
一般中斷分為上半部和下半部,中斷處理函數是在下半部,中斷屏蔽只是在上半部;你應該先了解中斷原理在來看代碼,你應該先看一下《深入理解linux內核》這本書的中斷部分

❺ 說明現代計算機採用中斷的原因,闡述Linux操作系統的中斷機制,它為什麼採用內核機制

提高計算機的運行效率,准確的說是CPU的效率。舉個例子,比如程序要進行格式化磁碟,那麼這個操作要十分鍾,那麼如果沒有中斷機制,那麼CPU要一直在那裡等待操作的完成,之後再執行後面的任務。在等的時候任何請求的不響應。如果有中斷,那麼就可以讓磁碟先去格式化,CPU就執行其他任務,當格式化完成時,以中斷的方式打斷CPU,通知CPU格式化操作完成。

❻ Linux 系統中的中斷是不是沒有中斷優先順序

關於中斷嵌套:在linux內核里,如果驅動在申請注冊中斷的時候沒有特別的指定,do_irq在做中斷響應的時候,是開啟中斷的,如果在驅動的中斷處理函數正在執行的過程中,出現同一設備的中斷或者不同設備的中斷,這時候新的中斷會被立即處理,還是被pending,等當前中斷處理完成後,再做處理。在2.4和2.6內核里,關於這一塊是否有什麼不同。 一般申請中斷的時候都允許開中斷,即不使用SA_INTERRUPT標志。如果允許共享則加上 SA_SHIRQ,如果可以為內核熵池提供熵值(譬如你寫的驅動是ide之類的驅動),則再加上 SA_SAMPLE_RANDOM標志。這是普通的中斷請求過程。對於這種一般情況,只要發生中斷,就可以搶占內核,即使內核正在執行其他中斷函數。這里有兩點說明:一是因為linux不支持 中斷優先順序,因此任何中斷都可以搶占其他中斷,但是同種類型的中斷(即定義使用同一個 中斷線的中斷)不會發生搶占,他們會在執行本類型中斷的時候依次被調用執行。二是所謂 只要發生中斷,就可以搶占內核這句是有一定限制的,因為當中斷發生的時候系統由中斷門 進入時自動關中斷(對於x86平台就是將eflags寄存器的if位置為0),只有當中斷函數被執行 (handle_IRQ_event)的過程中開中斷之後才能有搶占。 對於同種類型的中斷,由於其使用同樣的idt表項,通過其狀態標志(IRQ_PENDING和 IRQ_INPROGRESS)可以防止同種類型的中斷函數執行(注意:是防止handle_IRQ_event被重入, 而不是防止do_IRQ函數被重入),對於不同的中斷,則可以自由的嵌套。因此,所謂中斷嵌套, 對於不同的中斷是可以自由嵌套的,而對於同種類型的中斷,是不可以嵌套執行的。以下簡單解釋一下如何利用狀態標志來防止同種類型中斷的重入:當某種類型的中斷第一次發生時,首先其idt表項的狀態位上被賦予IRQ_PENDING標志,表示有待處理。 然後將中斷處理函數action置為null,然後由於其狀態沒有IRQ_INPROGRESS標志(第一次),故將其狀態置上IRQ_INPROGRESS並去處IRQ_PENDING標志,同時將action賦予相應的中斷處理函數指針(這里是一個重點,linux很巧妙的用法,隨後說明)。這樣,後面就可以順利執行handle_IRQ_event進行中斷處理,當在handle_IRQ_event中開中斷後,如果有同種類型的中斷發生,則再次進入do_IRQ函數,然後其狀態位上加上IRQ_PENDING標志,但是由於前一次中斷處理中加上的IRQ_INPROGRESS沒有被清除,因此這里無法清除IRQ_PENDING標志,因此action還是為null,這樣就無法再次執行handle_IRQ_event函數。從而退出本次中斷處理,返回上一次的中斷處理函數中,即繼續執行handle_IRQ_event函數。當handle_IRQ_event返回時檢查IRQ_PENDING標志,發現存在這個標志,說明handle_IRQ_event執行過程中被中斷過,存在未處理的同類中斷,因此再次循環執行handle_IRQ_event函數。直到不存在IRQ_PENDING標志為止。2.4和2.6的差別,就我來看,主要是在2.6中一進入do_IRQ,多了一個關閉內核搶占的動作,同時在處理中多了一種對IRQ_PER_CPU類型的中斷的處理,其他沒有什麼太大的改變。這類IRQ_PER_CPU的中斷主要用在smp環境下將中斷綁定在某一個指定的cpu上。例如arch/ppc/syslib/open_pic.c中的openpic_init中初始化ipi中斷的時候。 其實簡單的說,中斷可以嵌套,但是同種類型的中斷是不可以嵌套的,因為在IRQ上發生中斷,在中斷響應的過程中,這個IRQ是屏蔽的,也就是這個IRQ的中斷是不能被發現的。 同時在內核的臨界區內,中斷是被禁止的 關於do_IRQ可能會丟失中斷請求:do_IRQ函數是通過在執行完handle_IRQ_event函數之後判斷status是否被設置了IRQ_PENDING標志來判斷是否還有沒有被處理的同一通道的中斷請求。 但是這種方法只能判斷是否有,而不能知道有多少個未處理的統一通道中斷請求。也就是說,假如在第一個中斷請求執行handle_IRQ_event函數的過程中來了同一通道的兩個或更多中斷請求,而這些中斷不會再來,那麼僅僅通過判斷status是否設置了IRQ_PENDING標志不知道到底有多少個未處理的中斷,handle_IRQ_event只會被再執行一次。這算不算是個bug呢? 不算,只要知道有中斷沒有處理就OK了,知道1個和知道N個,本質上都是一樣的。作為外設,應當能夠處理自己中斷未被處理的情況。不可能丟失的,在每一個中斷描述符的結構體內,都有一個鏈表,鏈表中存放著服務常式序關於中斷中使用的幾個重要概念和關系: 一、基本概念 1. 產生的位置 發生的時刻 時序 中斷 CPU外部 隨機 非同步 異常 CPU正在執行的程序 一條指令終止執行後 同步 2.由中斷或異常執行的代碼不是一個進程,而是一個內核控制路徑,代表中斷發生時正在運行的進程的執行 中斷處理程序與正在運行的程序無關 引起異常處理程序的進程正是異常處理程序運行時的當前進程 二、特點 (2)能以嵌套的方式執行,但是同種類型的中斷不可以嵌套 (3)盡可能地限制臨界區,因為在臨界區中,中斷被禁止 2.大部分異常發生在用戶態,缺頁異常是唯一發生於內核態能觸發的異常 缺頁異常意味著進程切換,因此中斷處理程序從不執行可以導致缺頁的操作 3.中斷處理程序運行於內核態 中斷發生於用戶態時,要把進程的用戶空間堆棧切換到進程的系統空間堆棧,剛切換時,內核堆棧是空的 中斷發生於內核態時, 不需要堆棧空間的切換 三、分類 1.中斷的分類:可屏蔽中斷、不可屏蔽中斷 2.異常的分類: 分類 解決異常的方法 舉例 故障 那條指令會被重新執行 缺頁異常處理程序 陷阱 會從下一條指令開始執行 調試程序

❼ Linux能不能在進程中控制某個中斷開關

中斷是內核級別的機制
應用程序在用戶級別
用戶級別許可權低,是控制不了中斷的。
除非,你自己寫一個驅動(驅動也是運行在內核級別的),在這個驅動里去控制中斷,是ok的

❽ linux系統中的中斷指令是什麼

什麼是中斷
Linux 內核需要對連接到計算機上的所有硬體設備進行管理,毫無疑問這是它的份內事。如果要管理這些設備,首先得和它們互相通信才行,一般有兩種方案可實現這種功能:
輪詢(polling) 讓內核定期對設備的狀態進行查詢,然後做出相應的處理;中斷(interrupt) 讓硬體在需要的時候向內核發出信號(變內核主動為硬體主動)。
第一種方案會讓內核做不少的無用功,因為輪詢總會周期性的重復執行,大量地耗用 CPU 時間,因此效率及其低下,所以一般都是採用第二種方案 。
對於中斷的理解我們先看一個生活中常見的例子:QQ。第一種情況:你正在工作,然後你的好友突然給你發送了一個窗口抖動,打斷你正在進行的工作。第
二種情況:當然你有時候也會每隔 5 分鍾就去檢查一下 QQ
看有沒有好友找你,雖然這很浪費你的時間。在這里,一次窗口抖動就可以被相當於硬體的中斷,而你就相當於 CPU,你的工作就是 CPU
這在執行的進程。而定時查詢就被相當於 CPU 的輪詢。在這里可以看到:同樣作為 CPU 和硬體溝通的方式,中斷是硬體主動的方式,較輪詢(CPU
主動)更有效些,因為我們都不可能一直無聊到每隔幾分鍾就去查一遍好友列表。
CPU
有大量的工作需要處理,更不會做這些大量無用功。當然這只是一般情況下。好了,這里又有了一個問題,每個硬體設備都中斷,那麼如何區分不同硬體呢?不同設
備同時中斷如何知道哪個中斷是來自硬碟、哪個來自網卡呢?這個很容易,不是每個 QQ 號碼都不相同嗎?同樣的,系統上的每個硬體設備都會被分配一個
IRQ 號,通過這個唯一的 IRQ 號就能區別張三和李四了。
從物理學的角度看,中斷是一種電信號,由硬體設備產生,並直接送入中斷控制器(如
8259A)的輸入引腳上,然後再由中斷控制器向處理器發送相應的信號。處理器一經檢測到該信號,便中斷自己當前正在處理的工作,轉而去處理中斷。此後,
處理器會通知 OS 已經產生中斷。這樣,OS
就可以對這個中斷進行適當的處理。不同的設備對應的中斷不同,而每個中斷都通過一個唯一的數字標識,這些值通常被稱為中斷請求線。

❾ Linux下如何強制中斷一個程序的執行(利用按鍵,而不是kill命令)

Linux下強制中斷一個程序的執行,利用按鍵,而不是kill命令。

可嘗試以下方法:

1.CTRL + c中斷。

2.CTRL + z暫停放到後台。

3.CTRL + d保存退出。

❿ LINUX軟中斷通信

我驗證下阿...一不小心就fork多了..
剛開始我把kill的參數弄反了,信號和pid位置弄錯了,調了半個小時,很郁悶..

你只是忽略了一點...,我也給忽略了。。。後來才想起來

你按下ctrl+C的時候,另外兩個fork出來的進程,他們也會接到SIGINT。。。就退出了。。所以你要先在子進程裡面忽略這個SIGINT信號,用signal(SIGINT,SIG_IGN)就OK了....
程序如下...

有解釋,你可以自己看看...

#include"stdio.h"
#include"unistd.h"
#include"signal.h"
#include"sys/types.h"
#include"stdlib.h"

int k=0;
pid_t child1=0,child2=0;

void func_main(int sig);
void func_child1(int sig);
void func_child2(int sig);

int main()
{
while((child1=fork())==-1);
if(child1==0)
{
printf("child1 OK\n");
signal(SIGINT,SIG_IGN);
signal(SIGUSR1,func_child1);
sleep(60);
}

else if(child1 >0)
{
while((child2=fork())==-1);
if(child2==0)
{
printf("child 2 OK\n");
signal(SIGINT,SIG_IGN);//你按下ctrl+C,子進程也會接受到ctrl的信號...所以,子進程忽略
//所提子進程要忽略掉這個SIGINT信號
signal(SIGUSR2,func_child2);
sleep(60); //這里為了驗證,如果進程沒退出,40妙之後自動會退出的
//不然就得手動在終端裡面kill掉這個進程了...
//有時候成了僵屍進程需要kill -9 才能殺死
}

else if(child2 >0)
{
signal(SIGINT,func_main);
printf("children forked OK...\n");
wait(0);

printf("child return...\n");

sleep(100);
return 0;
}
}

}

void func_main(int sig)
{
k++;
printf("to send signal\n");
//printf("child1=%d,child2=%d\n",child1,child2);
//if(k==1)
kill(child1,SIGUSR1);
//if(k==2) 加上這句,再按一次ctrl C,子進程2才會退出
就是你想要的效果了
kill(child2,SIGUSR2);
signal(SIGINT,SIG_DFL); //這里恢復ctrl+C的效果
//子進程退出之後,我們再按一次ctrl+C,當前的父進程就會像平常一樣,退出。

}

void func_child1(int sig)
{
printf("child1 is killed by parent!\n");
exit(0);
}

void func_child2(int sig)
{
printf("child2 is killed by parent!\n");
exit(0);
}

熱點內容
公費訪問學者 發布:2024-09-29 03:33:12 瀏覽:308
雲主機源碼 發布:2024-09-29 03:18:28 瀏覽:661
cspython 發布:2024-09-29 02:58:07 瀏覽:737
下載加密日記軟體 發布:2024-09-29 02:58:07 瀏覽:799
晴天伺服器我的世界 發布:2024-09-29 02:57:58 瀏覽:447
怎麼滑動輸入密碼 發布:2024-09-29 02:31:45 瀏覽:231
pythonfinally 發布:2024-09-29 02:20:21 瀏覽:16
主播是什麼配置 發布:2024-09-29 01:40:21 瀏覽:199
晨曦軟體加密狗 發布:2024-09-29 01:40:18 瀏覽:308
浙江大學我的世界伺服器雲伺服器 發布:2024-09-29 01:40:14 瀏覽:64