萬盛學電腦網

 萬盛學電腦網 >> Linux教程 >> Linux--Linux內核模塊編程--阻塞進程在線閱讀

Linux--Linux內核模塊編程--阻塞進程在線閱讀

 阻塞進程
  當某人要求你什麼事而你當時不能時你在做什麼?如果你是人而你被別人打擾,你唯一能說的是:‘現在不行,我正忙著呢。 走開!’。但是如果你是一個內核模塊而你被一個進程打擾,你有另外的可能。你可以讓那個進程睡眠直到你能為它服務。畢竟,內核可以讓進程睡眠並且可以隨時喚醒它(那就是在單CPU上呈現同一時間多個進程運行的方式)。
  這個內核模塊就是這樣的例子。那個文件(被稱為 /proc/sleep)在同一時間只能被一個進程打開。如果那個文件已經打開了,內核模塊調用module_interruptible_sleep_on(保持一個文件打開的最簡單的辦法是用 tail -f)。這個函數改變那個任務(任何任務是包含有關進程的信息和系統調用的內核的一種數據結構)的狀態為TASK_INTERRUPTIBLE,它的意思是任務不能運行,除非它被喚醒。並且該任務被加入 WaitQ-- 等待訪問該文件的任務隊列。然後函數調用調度程序進行上下文轉換到一個還要使用CPU的不同的進程。
  當一個進程用完該文件,它關閉該文件,然後module_close 被調用。那個函數喚醒隊列中的所有進程(沒有機制只喚醒其中的一個)。然後它返回而剛剛關閉該文件的進程可以繼續運行。調度程序及時地決定那個進程已經用了夠多的時間而將CPU的控制權交給另一個進程。最後,隊列中的某個進程會獲得調度程序賦予的CPU的控制權。它正好在對module_interruptible_sleep_on(這意味著進程仍然在內核模式--直到進程被關照,它發布 open 系統調用然而系統調用還沒有返回。進程不知道別人在它發布調用和它返回之前的大部分時間內使用CPU)的調用後開始。然後它能繼續設置一個全局變量以告訴所有其他進程該文件仍然打開,它們將繼續它們等待的生活。當另一個進程得到CPU時間片,它們將看到那個全局變量而繼續去睡眠。
  為了使我們的生活更有趣, module_close 沒有喚醒等待訪問該文件的進程的壟斷權。一個信號,例如Ctrl-C (SIGINT)也可以喚醒一個進程(這是因為我們使用 module_interruptible_sleep_on。我們不能使用module_sleep_on 作為代替,但那將導致那些他們控制的計算機被忽略的用戶的極度的憤怒)。在那種情況下,我們想立即用 -EINTR 返回。這是很重要的,例如用戶因此可以在進程收到該文件前將它殺死。
  還有一點需要記住。有時候進程不想睡眠,它們想要麼立即得到它們需要的要麼被告知它不能完成。當文件打開時這類進程使用 O_NONBLOCK 標志。例如當文件打開時,內核被假設從阻塞操作中返回錯誤代碼-EAGAIN作為回應。在這章的源目錄中有的程序 cat_noblock 能用O_NONBLOCK打開文件。


copyright © 萬盛學電腦網 all rights reserved