linux下半部
❶ 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);
}
❷ linux 中斷 下半部 處理時間過長 怎麼辦
一、中斷處理為什麼要下半部?
Linux在中斷處理中間中斷處理分了上半部和下半部,目的就是提高系統的響應能力和並發能力。通俗一點來講:當一個中斷產生,調用該中斷對應的處理程序(上半部)然後告訴系統,對應的後半部可以執行了。然後中斷處理程序就返回,下半部會在合適的時機有系統調用。這樣一來就大大的減少了中斷處理所需要的時間。
二、那些工作應該放在上半部,那些應該放在下半部?
沒有嚴格的規則,只有一些提示:
1、對時間非常敏感,放在上半部。
2、與硬體相關的,放在上半部。
3、不能被其他中斷打斷的工作,放在上半部。
以上三點之外的,考慮放在下半部。
三、下半部機制在Linux中是怎麼實現的?
下半部在Linux中有以下實現機制:
1、BH(在2.5中刪除)
2、任務隊列(task queue,在2.5刪除)
3、軟中斷(softirq,2.3開始。本文重點)
4、tasklet(2.3開始)
5、工作隊列(work queue,2.5開始)
四、軟中斷是怎麼實現的(以下代碼出自2.6.32)?
軟中斷不會搶占另外一個軟中斷,唯一可以搶占軟中斷的是中斷處理程序。
軟中斷可以在不同CPU上並發執行(哪怕是同一個軟中斷)
1、軟中斷是編譯期間靜態分配的,定義如下:
struct softirq_action { void (*action)(struct softirq_action *); };
/*
* PLEASE, avoid to allocate new softirqs, if you need not _really_ high
* frequency threaded job scheling. For almost all the purposes
* tasklets are more than enough. F.e. all serial device BHs et
* al. should be converted to tasklets, not to softirqs.
*/
enum {
HI_SOFTIRQ=0,
TIMER_SOFTIRQ,
NET_TX_SOFTIRQ,
NET_RX_SOFTIRQ,
BLOCK_SOFTIRQ,
BLOCK_IOPOLL_SOFTIRQ,
TASKLET_SOFTIRQ,
SCHED_SOFTIRQ,
HRTIMER_SOFTIRQ,
RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */
NR_SOFTIRQS
};
/*
* map softirq index to softirq name. update 'softirq_to_name' in * kernel/softirq.c when adding a new softirq.
*/
extern char *softirq_to_name[NR_SOFTIRQS];
static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp;
說明:
(1)、軟中斷的個數書上說是32,看來到這個版本已經發生變化了。
(2)、void (*action)(struct softirq_action *);傳遞整個結構體指針在於當結構體成員發生變化是,介面不變。
2、系統執行軟中斷一個注冊的軟中斷必須被標記後才會執行(觸發軟中斷),通常中斷處理程序會在返回前標記它的軟中斷。在下列地方,待處理的軟中斷會被執行:
(1)、從一個硬體中斷代碼處返回。
(2)、在ksoftirqd內核線程。
(3)、在那些顯示檢查和執行待處理的軟中斷代碼中。
ksoftirqd說明:
每個處理器都有一個這樣的線程。所有線程的名字都叫做ksoftirq/n,區別在於n,它對應的是處理器的編號。在一個雙CPU的機器上就有兩個這樣的線程,分別叫做ksoftirqd/0和ksoftirqd/1。為了保證只要有空閑的處理器,它們就會處理軟中斷,所以給每個處理器都分配一個這樣的線程。
執行軟中斷的代碼如下:
asmlinkage void __do_softirq(void)
{
struct softirq_action *h;
__u32 pending;
int max_restart = MAX_SOFTIRQ_RESTART;
int cpu;
pending = local_softirq_pending();
account_system_vtime(current);
__local_bh_disable((unsigned long)__builtin_return_address(0));
lockdep_softirq_enter();
cpu = smp_processor_id();
restart:
/* Reset the pending bitmask before enabling irqs */
set_softirq_pending(0);
local_irq_enable();
h = softirq_vec;
do {
if (pending & 1) {
int prev_count = preempt_count();
kstat_incr_softirqs_this_cpu(h - softirq_vec);
trace_softirq_entry(h, softirq_vec);
h->action(h);
trace_softirq_exit(h, softirq_vec);
if (unlikely(prev_count != preempt_count())) {
printk(KERN_ERR "huh, entered softirq %td %s %p"
"with preempt_count %08x,"
" exited with %08x?\n", h - softirq_vec,
softirq_to_name[h - softirq_vec],
h->action, prev_count, preempt_count());
preempt_count() = prev_count;
}
rcu_bh_qs(cpu);
}
h++;
pending >>= 1;
} while (pending);
local_irq_disable();
pending = local_softirq_pending();
if (pending && --max_restart)
goto restart;
if (pending)
wakeup_softirqd();
lockdep_softirq_exit();
account_system_vtime(current);
_local_bh_enable();
}
3、編寫自己的軟中斷
(1)、分配索引,在HI_SOFTIRQ與NR_SOFTIRQS中間添加自己的索引號。
(2)、注冊處理程序,處理程序:open_softirq(索引號,處理函數)。
(3)、觸發你的軟中斷:raise_softirq(索引號)。
4、軟中斷處理程序注意
(1)、軟中斷處理程序執行的時候,允許響應中斷,但自己不能休眠。
(2)、如果軟中斷在執行的時候再次觸發,則別的處理器可以同時執行,所以加鎖很關鍵。
❸ 為什麼Linux系統設計了三種不同的下半部處理機制
為了應對不同的業務需求
軟中斷和tasklet都是不可中斷的下半部,但是軟中斷是有個數限制的,一般目前這個不會隨便增加,用於對實時性要求比較高的處理。tasklet是用軟中斷實現的,但是它沒有個數限制,它利用軟中斷和自己的鏈表結構可以實現數量不受限制的下半部處理。如果不希望自己的處理被掛起,但是又不是特殊的業務,一般都放在tasklet里了。
工作隊列則是可以掛起的,是在內核線程中執行的,也就是可以調度。
❹ 為什麼linux系統設計了三種不同的下半部處理機制
為了應對不同的業務需求 軟中斷和tasklet都是不可中斷的下半部,但是軟中斷是有個數限制的,一般目前這個不會隨便增加,用於對實時性要求比較高的處理。tasklet是用軟中斷實現的,但是它沒有個數限制,它利用軟中斷和自己的鏈表結構可以實現數量...
❺ linux中斷的下半部機制有哪些
一、中斷處理為什麼要下半部?Linux在中斷處理中間中斷處理分了上半部和下半部,目的就是提高系統的響應能力和並發能力。通俗一點來講:當一個中斷產生,調用該中斷對應的處理程序(上半部)然後告訴系統,對應的後半部可以執行了。然後中斷處理程序就返回,下半部會在合適的時機有系統調用。這樣一來就大大的減少了中斷處理所需要的時間。
二、那些工作應該放在上半部,那些應該放在下半部?
沒有嚴格的規則,只有一些提示:
1、對時間非常敏感,放在上半部。
2、與硬體相關的,放在上半部。
3、不能被其他中斷打斷的工作,放在上半部。
以上三點之外的,考慮放在下半部。
三、下半部機制在Linux中是怎麼實現的?
下半部在Linux中有以下實現機制:
1、BH(在2.5中刪除)
2、任務隊列(task queue,在2.5刪除)
3、軟中斷(softirq,2.3開始。本文重點)
4、tasklet(2.3開始)
5、工作隊列(work queue,2.5開始)
四、軟中斷是怎麼實現的(以下代碼出自2.6.32)?
軟中斷不會搶占另外一個軟中斷,唯一可以搶占軟中斷的是中斷處理程序。
軟中斷可以在不同CPU上並發執行(哪怕是同一個軟中斷)
1、軟中斷是編譯期間靜態分配的,定義如下:
struct softirq_action { void (*action)(struct softirq_action *); };
/*
* PLEASE, avoid to allocate new softirqs, if you need not _really_ high
* frequency threaded job scheling. For almost all the purposes
* tasklets are more than enough. F.e. all serial device BHs et
* al. should be converted to tasklets, not to softirqs.
*/
enum {
HI_SOFTIRQ=0,
TIMER_SOFTIRQ,
NET_TX_SOFTIRQ,
NET_RX_SOFTIRQ,
BLOCK_SOFTIRQ,
BLOCK_IOPOLL_SOFTIRQ,
TASKLET_SOFTIRQ,
SCHED_SOFTIRQ,
HRTIMER_SOFTIRQ,
RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */
NR_SOFTIRQS
❻ Linux中斷 異常 系統調用 中斷上半部 中斷下半部 這些有什麼區別和聯系
中斷分軟中斷跟硬中斷,硬中斷是由硬體從外部觸發,軟中斷由軟體觸發,就像linux系統調用int 80一樣。至於中斷的上下部其實就是因為中斷的處理時間跟它的優先順序不一定成正比,所以一般先處理中斷最重要的部分(上半部),待到不怎麼忙的時候,再來處理比較悠閑的部分(下半部)。就像輸入的時候,拿到鍵盤輸入的是什麼才是最重要的(上半部),顯示字元才是次要的(下半部)。
❼ linux內核中斷處理為什麼分成上半部分和下半部分
一、中斷處理為什麼要下半部? Linux在中斷處理中間中斷處理分了上半部和下半部,目的就是提高系統的響應能力和並發能力。通俗一點來講:當一個中斷產生,調用該中斷對應的處理程序(上半部)然後告訴系統,對應的後半部可以執行了。然後中斷處理...
❽ Linux綜合應用題編寫tasklet,在下半部分中列印當前進程的PID狀態和名字
假設進程pid是14186,命令如下
ps u -p 14186
❾ 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中斷中下半部調用tasklet的問題
一般來說,處理中斷都希望越快越好吧?為什麼你需要「處理稍微慢速點的操作」?大多數情況下,tasklet機制是實現控制一個尋常的硬體設備的最佳選擇,tasklet是利用軟中斷實現的一種下半部機制,所以不能睡眠,所以你不能在tasklet中使用信號量或者其他什麼阻塞式函數,tasklet允許響應中斷,如果你的tasklet和中斷處理程序之間共享了某些數據的話,你需要做好預防工作,比如屏蔽中斷然後獲取一個鎖。兩個相同的tasklet決不會同時執行,這點和軟中斷不同。如果你的tasklet和其他tasklet或者軟中斷共享了數據,你必須進行適當的鎖保護。