讀書筆記 程序管理(2 6核心)之二

2021-05-21 17:06:40 字數 2993 閱讀 6723

接上一節

task_unintrruptible不可中斷等待狀態

task_zombie僵死狀態,程序已經結束,但資源沒有釋放

task_stop程序停止執行

9 程序狀態間的轉換:

現存的程序呼叫fork()函式並建立新的程序,則程序進入task_running就緒但還未執行,當通過schedule()

函式呼叫context——switch()函式是進入task_ruuning執行狀態,在該狀態下呼叫do_exit()函式時就會進入

task_zombie任務被終止,但是如果任務被優先順序更高的任務搶占則進入task_running就緒狀態,如果為了等待特定事件

,任務在等待佇列上睡眠就會進入task_intrruptible或者task_unintrruptible等待,在task_intrruptible或者task_unintrruptible狀態下,等待的事件發生後任務被喚醒並且被重新置入執行佇列中而進入task_running就緒狀態。

10 可以呼叫set_task_state(task,state)函式設定程序的狀態。即執行task—>state=state

11 理解程序上下文:

當乙個程序在執行時,cpu的所有暫存器中的值、程序的狀態以及堆疊中的內容被稱為該程序的上下文。當核心需要切換到另乙個程序時,它需要儲存當前程序的所有狀態,即儲存當前程序的上下文,以便在再次執行該程序時,能夠必得到切換時的狀態執行下去。在linux中,當前程序上下文均儲存在程序的任務資料結構中。在發生中斷時,核心就在被中斷程序的上下文中,在核心態下執行中斷服務例程。但同時會保留所有需要用到的資源,以便中繼服務結束時能恢復被中斷程序的執行。

12 在linux系統中所有的程序都是pid為1的init程序的後代。

每個程序必有乙個父程序。

每個程序可以有0個獲多個程序。

擁有同乙個父程序的所有程序被稱為兄弟

每個task_struct都包含有乙個指向其父程序task_struct叫做parent的指標還包含乙個稱為children的子程序的鍊錶

任務佇列是乙個雙向迴圈鍊錶

13 list_entry(task->tasks.next,struct task_struct,tasks)獲取下乙個鍊錶中的程序

list_entry(task->tasks.prev,struct task_struct,tasks)獲取前乙個鍊錶中的程序

14 linux的fork()使用寫時拷貝頁實現

fork()的實際開銷就是複製父程序的頁表以及給子程序建立唯一的程序描述符

15 linux通過clone()系統呼叫實現fork(),然後由clone()去呼叫do_fork(),該函式的定義在kernel/fork.c中,該函式又呼叫copy_process()函式,然後讓程序開始執行。

copy_process()函式執行的工作有:

....dup_task_struct()為新程序建立乙個核心棧、thread_info結構和task_struct,這些值與父程序的值相同,子程序和父程序的描述符完全相同

....檢查當前使用者所擁有的程序數目沒有超出分配給的資源限制

....子程序的程序描述符內的成員要被清0或者設定為初值

....子程序的狀態設定為task_unintrruptible以保證它不會投入執行

....呼叫copy_flags()更新task_struct的flags成員。表明程序是否擁有超級使用者的許可權pf_superprv=0,表明程序還沒有呼叫exec()函式的pf_fornoexec標誌被設定

....呼叫get_pid()為新程序獲取有效地pid

....根據傳遞給clone()的引數標誌,copy_process()拷貝或共享開啟的檔案、檔案系統資訊、訊號處理函式、程序位址空間和命名空間

....讓父程序和子程序平分剩餘的時間片

....返回乙個指向子程序的指標

16 linux把所有的執行緒都當做程序來實現,執行緒被視為乙個與其他程序共享某些資源的程序

核心執行緒建立乙個新的核心執行緒的方法

int kernel_thread(int (*fn)(void *),void *arg,unsigned long flags)

17 程序的析構發生在它呼叫exit()之後,可以顯示的呼叫,也可以隱式的從某個程式的主函式返回其將呼叫do_exit()函式

該函式完成的工作是:

。。。。將task_struct中的標誌成員設定為pf_exiting

。。。。呼叫del_timer_sync()刪除任一核心定時器,以確保沒有定時器在排隊也沒有定時器出來程式執行

。。。。如果bsd程序記賬功能開啟,則呼叫acct_process()輸出記賬資訊

。。。。呼叫_exit_mm()放棄程序占用的mm_struct

。。。。呼叫exit_sem(),

。。。。呼叫_exit_files()、_exit_fs()、exit_namespace()和exit_sighand(),以分別遞減檔案描述符、檔案系統資料、程序名字空間和訊號處理的引用計數

。。。。把存放在task_struct的exit_code成員中的任務退出

。。。。呼叫exit_notify()向父程序發生訊號,將子程序的父程序從新設定為執行緒組中的其他執行緒或init程序,並把程序狀態設為task_zombie

。。。。最後呼叫schedule()切換到其他的程序

do_exit()的實現在kernel/exit.c檔案中

18 呼叫release_task()釋放程序描述符,主要完成:

。。。。呼叫free_uid()來減少該程序擁有者的程序使用計數

。。。。呼叫unhash_process()從pidhash上刪除該程序,也要從task_list中刪除該程序

。。。。如果程序正在被跟蹤,release——task()將跟蹤的程序的父程序重設為其最初的父程序並將它從ptrace_list刪除

。。。。最後呼叫put_task_struct()釋放程序的核心棧和thread_info結構所佔頁,並釋放task_struct所佔的slab快取記憶體

19本章小結:了解程序的建立和刪除過程,程序和執行緒的區別

Effective C 讀書筆記 26

條款26 盡可能延後變數定義式的出現時間 當你定義乙個變數的時候就要保證這個變數能夠在程式中使用到,不要定義無意義的變數,這樣就要求我們最好是在變數使用 到 的時候才做定義,因為如果乙個變數定義了卻乜有使用可能會造成效率上的降低,畢竟很多變數的構建是要呼叫對應的建構函式 和析 構函式的,考慮下面的例...

人件讀書筆記之二

錯誤在所難免 對大多數腦力勞動者來說,工作偶爾出錯再自然不過,也很健康,沒什麼危害 但總有些教條主義者會把工作中的錯誤和罪惡聯絡起來 我們需要採取措施去改變這種態度面對一群軟體開發經理,我們介紹了一種迭代式設計的策略這個想法是針對那些天生容易出錯的設計的,我們應該徹底拋棄而不是去修復 這種設計活動上...

人機互動讀書筆記之二

使用者和產品接觸的全部過程稱為產品的全部使用者體驗 total user experience 使用者使用產品只是中間的乙個環節。全部使用者體驗包括從最初了解產品 具體研究 獲得產品 安裝使用,知道產品的各個方面的服務和更新。產品的設計和開發一般分為3個主要階段 1.策略和使用者分析 2.設計和評估...