萬盛學電腦網

 萬盛學電腦網 >> Linux教程 >> Linux--Linux內核模塊編程--替任務調度在線閱讀

Linux--Linux內核模塊編程--替任務調度在線閱讀

 任務調度
  常常的,我們有‘家務管理’的任務需要在某個時間做或者偶爾經常如此。如果任務由進程完成,我們可以將它放在 crontab 文件中。如果任務由內核模塊完成,我們有兩種可能。第一個是在 crontab 文件中放置一個在必要的時候通過系統調用喚醒模塊的進程,例如通過打開文件。這是非常低效的,然而--我們運行一個不在 crontab 中的新進程, 讀一個新的可執行的進程到內存,而所有這些只是喚醒在內存中的內核模塊。
  替代的,我們可以創建一個對每個定時器中斷被調用一次的函數。我們的辦法是創建一個包含在 tq_struct結構中的任務,而該結構包含該函數的指針。然後我們使用 queue_task 將那個任務放置在被稱為tq_timer 的任務列表中,該列表是在下一個定時器中斷將被執行的任務的列表。因為我們我們想該函數在下一次定時器中斷時繼續被執行,我們需要在它被調用後將它放回 tq_timer。
  這還有一點我們需要記住的。當一個模塊被 rmmod 移除時,它的引用計數器首先被檢查,如果它為0,module_cleanup 將被調用。然後模塊連同它的所有函數被從內存中清除。沒有人去檢查看在定時器任務列表中是否碰巧包含一個這樣的不再可見的函數的指針。一段時間後(從計算機的觀點看,而從人的觀點看它什麼也不是,它少於百分之一秒),內核有了一個定時器中斷並試圖去調用任務列表中的函數。不幸的,那個函數不在那兒。在大多情況下它剛才所在內存頁沒有被使用,而你會得到一個難看的錯誤消息。但是如果別的某些代碼現在位於同一個內存位置,事情會變得 非常 難看。不幸的,我們沒有一個簡單的辦法將一個任務從任務列表中注銷。
  既然 cleanup_module 不能返回錯誤代碼(它是一個void函數),解決的辦法是根本不讓它返回。替代的,它調用sleep_on 或 module_sleep_on(他們實際上是相同的。 )使 rmmod 進程睡眠。在此之前,它通過設置一個全局變量通知在定時器中斷將被調用的函數停止連接自己。然後,在下一次定時器中斷, rmmod進程被喚醒,當我們的函數不再在那個隊列中時移除那個模塊就是安全的了。


copyright © 萬盛學電腦網 all rights reserved