校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁 > 知識庫 > Linux之時鐘中斷詳解

Linux之時鐘中斷詳解

熱門標簽:電銷機器人加盟多少錢 申請400電話有什么用 400電話申請找 網絡電話外呼系統撥號軟件 貴陽400電話到哪里去辦理 宿松高德地圖標注 汨羅代理外呼系統 4層電梯外呼控制系統設計 天津智能外呼系統排名

在Linux的0號中斷是一個定時器中斷。在固定的時間間隔都發生一次中斷,也是說每秒發生該中斷的頻率都是固定的。該頻率是常量HZ,該值一般是在100 ~ 1000之間。該中斷的作用是為了定時更新系統日期和時間,使系統時間不斷地得到跳轉。另外該中斷的中斷處理函數除了更新系統時間外,還需要更新本地CPU統計數。指的是調用scheduler_tick遞減進程的時間片,若進程的時間片遞減到0,進程則被調度出去而放棄CPU使用權。

時鐘中斷的產生

Linux的OS時鐘的物理產生原因是可編程定時/計數器產生的輸出脈沖,這個脈沖送入CPU,就可以引發一個中斷請求信號,我們就把它叫做時鐘中斷。

“時鐘中斷”是特別重要的一個中斷,因為整個操作系統的活動都受到它的激勵。系統利用時鐘中斷維持系統時間、促使環境的切換,以保證所有進程共享CPU;利用時鐘中斷進行記帳、監督系統工作以及確定未來的調度優先級等工作。可以說,“時鐘中斷”是整個操作系統的脈搏。

時鐘中斷的物理產生如圖所示:

操作系統對可編程定時/計數器進行有關初始化,然后定時/計數器就對輸入脈沖進行計數(分頻),產生的三個輸出脈沖Out0、Out1、Out2各有用途,很多接口書都介紹了這個問題,我們只看Out0上的輸出脈沖,這個脈沖信號接到中斷控制器8259A_1的0號管腳,觸發一個周期性的中斷,我們就把這個中斷叫做時鐘中斷,時鐘中斷的周期,也就是脈沖信號的周期,我們叫做“滴答”或“時標”(tick)。從本質上說,時鐘中斷只是一個周期性的信號,完全是硬件行為,該信號觸發CPU去執行一個中斷服務程序,但是為了方便,我們就把這個服務程序叫做時鐘中斷。

Linux實現時鐘中斷的全過程

1.可編程定時/計數器的初始化

IBM PC中使用的是8253或8254芯片。有關該芯片的詳細知識我們不再詳述,只大體介紹以下它的組成和作用,如下表5.1所示:

表 8253/8254的組成及作用

名稱

端口地址

工作方式

產生的輸出脈沖的用途

計數器0

0x40

方式3

時鐘中斷,也叫系統時鐘

計數器1

0x41

方式2

動態存儲器刷新

計數器2

0x42

方式3

揚聲器發聲

控制寄存器

0x43

/

用于8253的初始化,接收控制字

計數器0的輸出就是圖中的Out0,它的頻率由操作系統的設計者確定,Linux對8253的初始化程序段如下(在/arch/i386/kernel/i8259.c的init_IRQ()函數中):

set_intr_gate(ox20, interrupt[0]); 
 
/*在IDT的第0x20個表項中插入一個中斷門。這個門中的段選擇符設置成內核代碼段的選擇符,偏移域設置成0號中斷處理程序的入口地址。*/ 
 
outb_p(0x34,0x43);  /* 寫計數器0的控制字:工作方式2*/ 
 
outb_p(LATCH  0xff , 0x40); /* 寫計數初值LSB 計數初值低位字節*/ 
 
outb(LATCH >> 8 , 0x40); /* 寫計數初值MSB 計數初值高位字節*/ 
 
LATCH(英文意思為:鎖存器,即其中鎖存了計數器0的初值)為計數器0的計數初值,在/include/linux/timex.h中定義如下: 
 
#define CLOCK_TICK_RATE 1193180 /* 圖5.3中的輸入脈沖 */ 
 
#define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* 計數器0的計數初值 */ 

CLOCK_TICK_RATE是整個8253的輸入脈沖,如圖5.3中所示為1.193180MHz,是近似為1MHz的方波信號,8253內部的三個計數器都對這個時鐘進行計數,進而產生不同的輸出信號,用于不同的用途。

HZ表示計數器0的頻率,也就是時鐘中斷或系統時鐘的頻率,在/include/asm/param.h中定義如下:

#define HZ 100

2.與時鐘中斷相關的函數

下面我們看時鐘中斷觸發的服務程序,該程序代碼比較復雜,分布在不同的源文件中,主要包括如下函數:

時鐘中斷程序:timer_interrupt( );

中斷服務通用例程do_timer_interrupt();

時鐘函數:do_timer( );

中斷安裝程序:setup_irq( );

中斷返回函數:ret_from_intr( );

(1) timer_interrupt( )

這個函數大約每10ms被調用一次,實際上, timer_interrupt( )函數是一個封裝例程,它真正做的事情并不多,但是,作為一個中斷程序,它必須在關中斷的情況下執行。如果只考慮單處理機的情況,該函數主要語句就是調用do_timer_interrupt()函數。

(2) do_timer_interrupt()

do_timer_interrupt()函數有兩個主要任務,一個是調用do_timer( ),另一個是維持實時時鐘(RTC,每隔一定時間段要回寫),其實現代碼在/arch/i386/kernel/time.c中, 為了突出主題,筆者對以下函數作了改寫,以便于讀者理解:

static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) 
{ 
 do_timer(regs); /* 調用時鐘函數,將時鐘函數等同于時鐘中斷未嘗不可*/ 
 if(xtime.tv_sec > last_rtc_update + 660) 
 update_RTC(); 
 /*每隔11分鐘就更新RTC中的時間信息,以使OS時鐘和RTC時鐘保持同步,11分鐘即660秒,xtime.tv_sec的單位是秒,last_rtc_update記錄的是上次RTC更新時的值 */             
} 

其中,xtime是前面所提到的timeval類型,這是一個全局變量。

(3) 時鐘函數do_timer() (在/kernel/sched.c中)

void do_timer(struct pt_regs * regs) 
{ 
 (*(unsigned long *)jiffies)++; /*更新系統時間,這種寫法保證對jiffies 
 
操作的原子性*/ 
 update_process_times(); 
 ++lost_ticks; 
 if( ! user_mode ( regs ) ) 
  ++lost_ticks_system; 
  mark_bh(TIMER_BH);    
 if (tq_timer)      
  mark_bh(TQUEUE_BH); 
} 

其中,update_process_times()函數與進程調度有關,從函數的名子可以看出,它處理的是與當前進程與時間有關的變量,例如,要更新當前進程的時間片計數器counter,如果counter=0,則要調用調度程序,要處理進程的所有定時器:實時、虛擬、概況,另外還要做一些統計工作。

與時間有關的事情很多,不能全都讓這個函數去完成,這是因為這個函數是在關中斷的情況下執行,必須處理完最重要的時間信息后退出,以處理其他事情。那么,與時間相關的其他信息誰去處理,何時處理?這就是由第三章討論的后半部分去去處理。 上面timer_interrupt()(包括它所調用的函數)所做的事情就是上半部分。

在該函數中還有兩個變量lost_ticks和lost_ticks_system,這是用來記錄timer_bh()執行前時鐘中斷發生的次數。因為時鐘中斷發生的頻率很高(每10ms一次),所以在timer_bh()執行之前,可能已經有時鐘中斷發生了,而timer_bh()要提供定時、記費等重要操作,所以為了保證時間計量的準確性,使用了這兩個變量。lost_ticks用來記錄timer_bh()執行前時鐘中斷發生的次數,如果時鐘中斷發生時當前進程運行于內核態,則lost_ticks_system用來記錄timer_bh()執行前在內核態發生時鐘中斷的次數,這樣可以對當前進程精確記費。

(4)中斷安裝程序

從上面的介紹可以看出,時鐘中斷與進程調度密不可分,因此,一旦開始有時鐘中斷就可能要進行調度,在系統進行初始化時,所做的大量工作之一就是對時鐘進行初始化,其函數time_init ()的代碼在/arch/i386/kernel/time.c中,對其簡寫如下:

 void __init time_init(void) 
 { 
xtime.tv_sec=get_cmos_time(); 
xtime.tv_usec=0; 
setup_irq(0,&irq0); 
} 

其中的get_cmos_time()函數就是把當時的實際時間從CMOS時鐘芯片讀入變量xtime中,時間精度為秒。而setup_irq(0,&irq0)就是時鐘中斷安裝函數,那么irq0指的是什么呢,它是一個結構類型irqaction,其定義及初值如下:

static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL};

setup_irq(0, irq0)的代碼在/arch/i386/kernel/irq.c中,其主要功能就是將中斷程序連入相應的中斷請求隊列,以等待中斷到來時相應的中斷程序被執行。

struct irqaction { 
  irq_handler_t handler;  //中斷處理函數,注冊時提供  
  unsigned long flags;   //中斷標志,注冊時提供  
  cpumask_t mask;    //中斷掩碼  
  const char *name;   //中斷名稱 
  void *dev_id;      //設備id,本文后面部分介紹中斷共享時會詳細說明這個參數的作用 
  struct irqaction *next;  //如果有中斷共享,則繼續執行,  
  int irq;        //中斷號,注冊時提供 
  struct proc_dir_entry *dir; //指向IRQn相關的/proc/irq/n目錄的描述符 
}; 

這個結構體包含了處理一種中斷所需要的各種信息,它代表了內核接受到特定IRQ之后應該采取的操作。

1.handler:該指針所指向的函數就是在中斷服務程序,當中斷發生時內核便會調用這個指針指向的函數。

2.flags:該標志位可以是0,也可以是:

SA_INTERRUPT:表示此中斷處理程序是一個快速中斷處理程序,在2.6中默認情況下沒有這個標志;設置該標志位,中斷處理程序禁止任何中斷運行,沒有該標志,僅屏蔽正在運行的IRQ線;

SA_SAMPLE_RANDOM:表示這個中斷對內核池有貢獻,在中斷時產生一些隨機數;

SA_SHIRQ:此標志位表示允許多個中斷服務程序共享一個中斷號,如不設則一個程序對應一個中斷線;

3.mask:在x86上不會用到。

4.name:產生中斷的硬件的名字.

5.dev_id:該標志位主要在共享中斷號時使用,即你設置flags=SA_SHIRQ時,有多個中斷服務程序共享一個中斷號時,內核就需要知道在用完中斷程序后該刪除那個中斷服務程序。不共享時此成員為null。

6.next:如果flags=SA_SHIRQ,那么這就是指向對列中下一個struct irqaction結構體的指針,否則為空。

7.irq:不用說這就是中斷號了。

到現在為止,我們僅僅是把時鐘中斷程序掛入中斷請求隊列,什么時候執行,怎樣執行,這是一個復雜的過程(參見第三章),為了讓讀者對時鐘中斷有一個完整的認識,我們忽略中間過程,而給出一個整體描述。我們將有關函數改寫如下,體現時鐘中斷的大意:

do_timer_interrupt( )   /*這是一個偽函數 */ 
{            
 SAVE_ALL     /*保存處理機現場 */ 
 intr_count += 1;    /* 這段操作不允許被中斷 */ 
 timer_interrupt()    /* 調用時鐘中斷程序 */ 
 intr_count -= 1;    
 jmp ret_from_intr    /* 中斷返回函數 */ 
} 

其中,jmp ret_from_intr 是一段匯編代碼,也是一個較為復雜的過程,它最終要調用jmp ret_from_sys_call,即系統調用返回函數,而這個函數與進程的調度又密切相關,,因此,我們重點分析 jmp ret_from_sys_call。

3.系統調用返回函數:

系統調用返回函數的源代碼在/arch/i386/kernel/entry.S中

ENTRY(ret_from_sys_call) 
   cli     # need_resched and signals atomic test 
   cmpl $0,need_resched(%ebx) 
   jne reschedule 
   cmpl $0,sigpending(%ebx) 
   jne signal_return 
 restore_all: 
   RESTORE_ALL 
   ALIGN 
 signal_return: 
   sti    # we can get here from an interrupt handler 
   testl $(VM_MASK),EFLAGS(%esp) 
   movl %esp,%eax 
   jne v86_signal_return 
   xorl %edx,%edx 
   call SYMBOL_NAME(do_signal) 
   jmp restore_all 
   ALIGN 
  v86_signal_return: 
   call SYMBOL_NAME(save_v86_state) 
   movl %eax,%esp 
   xorl %edx,%edx 
   call SYMBOL_NAME(do_signal) 
   jmp restore_all 
 …. 
 reschedule: 
   call SYMBOL_NAME(schedule) # test 
  jmp ret_from_sys_call 

這一段匯編代碼就是前面我們所說的“從系統調用返回函數”ret_from_sys_call,它是從中斷、異常及系統調用返回時的通用接口。這段代碼主體就是ret_from_sys_call函數,其執行過程中要調用其它一些函數(實際上是一段代碼,不是真正的函數),在此我們列出相關的幾個函數:

(1)ret_from_sys_call:主體

(2)reschedule:檢測是否需要重新調度

(3)signal_return:處理當前進程接收到的信號

(4)v86_signal_return:處理虛擬86模式下當前進程接收到的信號

(5)RESTORE_ALL:我們把這個函數叫做徹底返回函數,因為執行該函數之后,就返回到當前進程的地址空間中去了。

可以看到ret_from_sys_call的主要作用有:

檢測調度標志need_resched,決定是否要執行調度程序;處理當前進程的信號;恢復當前進程的環境使之繼續執行。

最后我們再次從總體上瀏覽一下時鐘中斷:

每個時鐘滴答,時鐘中斷得到執行。時鐘中斷執行的頻率很高:100次/秒,時鐘中斷的主要工作是處理和時間有關的所有信息、決定是否執行調度程序以及處理下半部分。和時間有關的所有信息包括系統時間、進程的時間片、延時、使用CPU的時間、各種定時器,進程更新后的時間片為進程調度提供依據,然后在時鐘中斷返回時決定是否要執行調度程序。下半部分處理程序是Linux提供的一種機制,它使一部分工作推遲執行。時鐘中斷要絕對保證維持系統時間的準確性,而下半部分這種機制的提供不但保證了這種準確性,還大幅提高了系統性能。

總結

以上就是本文關于Linux之時鐘中斷詳解的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續參閱本站其他相關專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!

您可能感興趣的文章:
  • 利用Linux中的crontab實現分布式項目定時任務功能
  • linux sudo密碼輸入時顯示星號的操作方法
  • 如何在Linux下設置錄音筆時間
  • Linux定時任務Crontab的使用方法
  • Linux/Unix關于時間和時間戳的命令行
  • Linux定時執行任務at和crontab命令詳解
  • 簡單談談Linux內核定時器
  • Linux 中unzip解壓時中文亂碼的解決辦法

標簽:廣東 臨沂 烏蘭察布 連云港 海北 撫州 昌都 贛州

巨人網絡通訊聲明:本文標題《Linux之時鐘中斷詳解》,本文關鍵詞  Linux,之,時鐘,中斷,詳解,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Linux之時鐘中斷詳解》相關的同類信息!
  • 本頁收集關于Linux之時鐘中斷詳解的相關信息資訊供網民參考!
  • 推薦文章
    校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃
    亚洲欧洲三级电影| 久久精品一区四区| 欧美精品一区二区精品网| 欧美一卡2卡3卡4卡| 国产亚洲欧洲997久久综合| 国产精品国产三级国产| 一区二区三区国产精华| 精品一区二区精品| 91免费观看视频| 精品国产免费人成在线观看| 欧美经典三级视频一区二区三区| 亚洲精品国久久99热| 国产精品一二三四五| 91久久线看在观草草青青 | 一二三四社区欧美黄| 亚洲色图在线看| 极品少妇xxxx偷拍精品少妇| 国产**成人网毛片九色| 日韩女优电影在线观看| 亚洲人成亚洲人成在线观看图片| 久久99国内精品| 在线视频综合导航| 亚洲精品一区二区在线观看| 视频一区视频二区在线观看| 国产99久久久国产精品| 日韩你懂的在线播放| 亚洲另类在线视频| 国产在线视视频有精品| 制服丝袜日韩国产| 中文字幕制服丝袜成人av| 国产曰批免费观看久久久| 欧美在线综合视频| 久久久亚洲国产美女国产盗摄 | 免费观看久久久4p| 99久久久免费精品国产一区二区| 久久久久久久网| 日本欧美大码aⅴ在线播放| 欧美日产在线观看| 中文字幕一区二区三区在线观看| 精品无人码麻豆乱码1区2区| 日韩精品一区在线| 午夜婷婷国产麻豆精品| 欧美午夜电影网| 一区二区三区在线视频观看58| 国产精品一区二区不卡| 日韩一区二区免费在线电影| 亚洲精品国产第一综合99久久 | 91精品久久久久久久久99蜜臂| 一区精品在线播放| 成人app在线观看| 国产精品色哟哟| 成人黄色av电影| 亚洲美女电影在线| 91香蕉视频污在线| 偷拍自拍另类欧美| 91精品福利在线一区二区三区 | 4438亚洲最大| 视频一区国产视频| 久久精品一区二区三区av| 精品一区二区三区日韩| 国产精品丝袜黑色高跟| 国产91精品精华液一区二区三区| 99精品欧美一区二区三区小说| 一区二区三区免费网站| 欧美影视一区在线| 国产在线视频一区二区| 久久嫩草精品久久久久| 92精品国产成人观看免费| 中文字幕五月欧美| 欧美放荡的少妇| 激情欧美一区二区三区在线观看| 精品久久久影院| 粉嫩欧美一区二区三区高清影视 | 欧美做爰猛烈大尺度电影无法无天| 亚洲欧洲日产国产综合网| 91啪在线观看| 性做久久久久久免费观看欧美| 欧美一二三在线| 国产精品资源网| 亚洲妇熟xx妇色黄| 欧美电影免费提供在线观看| 菠萝蜜视频在线观看一区| 一区二区三区不卡在线观看| 精品av久久707| 91在线小视频| 久久99精品国产麻豆不卡| 国产精品国产三级国产aⅴ无密码| 色哟哟在线观看一区二区三区| 久久se精品一区二区| 国产三级精品在线| 欧美精品在欧美一区二区少妇| 精品影视av免费| 香港成人在线视频| 国产欧美日韩在线看| 在线成人免费视频| youjizz国产精品| 美女一区二区三区在线观看| 亚洲天天做日日做天天谢日日欢| 一本一道久久a久久精品综合蜜臀| 九色综合狠狠综合久久| 亚洲黄色录像片| 亚洲天天做日日做天天谢日日欢| 欧美一级黄色录像| 欧美日韩国产一级二级| 国产精品一区二区在线播放 | 一区二区三区四区av| 精品国产不卡一区二区三区| 波多野洁衣一区| 成人激情午夜影院| 久久精品国产亚洲高清剧情介绍 | 欧美成人女星排行榜| 99久久免费视频.com| 国产成人av一区二区| 日韩激情av在线| 亚洲精品ww久久久久久p站| 国产偷国产偷亚洲高清人白洁| 3d动漫精品啪啪1区2区免费 | 69久久99精品久久久久婷婷| 91麻豆123| 成人av网站大全| www.亚洲激情.com| 国产成人午夜精品5599| 国产黄人亚洲片| 美女久久久精品| 国内精品久久久久影院一蜜桃| 午夜在线成人av| 美女www一区二区| 日韩成人dvd| 另类综合日韩欧美亚洲| 日韩成人一级片| 老司机免费视频一区二区三区| 午夜精品久久久久久久蜜桃app| 午夜天堂影视香蕉久久| 亚洲国产综合色| 看片的网站亚洲| 久久国产综合精品| 国产不卡视频在线观看| 国产毛片一区二区| 国产91清纯白嫩初高中在线观看| 国产精品996| 91在线免费播放| 一本大道久久a久久综合婷婷| 欧美婷婷六月丁香综合色| 色婷婷久久久综合中文字幕| 欧美美女bb生活片| 69成人精品免费视频| 久久精品综合网| 国产精品无遮挡| 亚洲图片欧美色图| 性欧美疯狂xxxxbbbb| 国产米奇在线777精品观看| 国产精品一区二区三区网站| 91丝袜呻吟高潮美腿白嫩在线观看| 99精品偷自拍| 在线观看日韩精品| 日韩一区二区在线观看视频播放| 欧美视频一区在线| 久久久蜜桃精品| 国产精品成人免费精品自在线观看 | 久久久久久免费| 亚洲人吸女人奶水| 亚洲午夜三级在线| 国产成人精品一区二区三区四区| 成人av在线资源网| 欧美一区日本一区韩国一区| 欧美zozo另类异族| 亚洲高清免费观看高清完整版在线观看 | 国产成人免费9x9x人网站视频| 色婷婷激情一区二区三区| 欧美三级电影一区| 国产精品免费aⅴ片在线观看| 一区二区在线电影| 国产传媒一区在线| 色网站国产精品| 国产喷白浆一区二区三区| 一区二区在线观看av| 国产剧情一区二区| 欧美中文字幕亚洲一区二区va在线 | 欧美激情在线一区二区三区| 亚洲妇女屁股眼交7| 国产麻豆视频一区| 欧美一级高清大全免费观看| 国产欧美一区二区三区沐欲| 蜜桃一区二区三区在线| 丁香婷婷深情五月亚洲| 欧美精品一区二区三区蜜臀| 国产精品美日韩| 国产一本一道久久香蕉| 欧美午夜在线观看| 亚洲欧美乱综合| 国产在线精品一区二区| 欧美日韩视频在线第一区| 国产精品三级视频| 人妖欧美一区二区| 一本久道中文字幕精品亚洲嫩| 国产精品久久久久永久免费观看 | 欧美日韩精品一区视频| 一区二区三区四区高清精品免费观看| 免播放器亚洲一区| 日韩欧美你懂的|