The mind is not a vessel that needs filling , but wood that needs igniting ! 1. 運轉CPU 程式計數器pc 將pc置一個初值,然後取值執行,cpu就運轉起來了 2. CPU沒有好好運轉 當遇到IO設備的時候,cpu得等待 ...
The mind is not a vessel that needs filling , but wood that needs igniting !
1. 運轉CPU
程式計數器pc
將pc置一個初值,然後取值執行,cpu就運轉起來了
2. CPU沒有好好運轉
當遇到IO設備的時候,cpu得等待
3. 得讓CPU好好運轉
當程式1執行到一個程式需要等著別的程式執行,那麼就先切到別的程式執行
怎麼切換,不就是pc的跳轉,利用棧來做
當只有一個棧的時候問題就出現了,
Yield:其作用是當前線程“放棄”執行,讓操作系統調度另一線程繼續執行
所以就出現了兩個棧+兩個用戶TCB(線程式控制制塊)
4. 一直在用戶態那怎麼行?
當前的再怎麼切都是在用戶切,根本進入不了內核
引入了內核棧的切換
5. 實現這個idea
在屏幕上交替的打出A和B
從用戶代碼開始:
fork是怎麼工作的?
- 一個進程,包括代碼、數據和分配給進程的資源。fork()函數通過系統調用創建一個與原來進程幾乎完全相同的進程,也就是兩個進程可以做完全相同的事,但如果初始參數或者傳入的變數不同,兩個進程也可以做不同的事。
- 一個進程調用fork()函數後,系統先給新的進程分配資源,例如存儲數據和代碼的空間。然後把原來的進程的所有值都複製到新的新進程中,只有少數值與原來的進程的值不同。相當於克隆了一個自己。
fork函數的特性?
fork調用的一個奇妙之處就是它僅僅被調用一次,卻能夠返回兩次,它可能有三種不同的返回值
- 在父進程中,fork返回新創建子進程的進程ID;
- 在子進程中,fork返回0;
- 如果出現錯誤,fork返回一個負值;
在fork函數執行完畢後,如果創建新進程成功,則出現兩個進程,一個是子進程,一個是父進程。在子進程中,fork函數返回0,在父進程中,fork返回新創建子進程的進程ID。我們可以通過fork返回的值來判斷當前進程是子進程還是父進程。
INT就進入了內核
然後就是執行system_call , 接下來就是sys_fork
接著開始copy_process
然後就開始返回
現在是創建好了一個列印A的進程,現在需要返回創建一個打B的進程
和上面類似,只是對應的tss->eip不同
然後父進程開始等待,也就是阻塞,然後調用schedule
總的來說:就是有一個進程,產生出兩個列印A和列印B的子進程,對應著列印A和列印B的函數,然後父進程阻塞調用schedule,schedule就開始選擇其中的一個進程(根據選擇演算法),這裡也就是列印A的進程,選擇完了就切換過去,
也就是把當前cpu中的信息拍到當前父進程中,然後把A的PCB中的tss扣到cpu上
這就切換過去了,而cpu一直就是取指執行,此時eip=100,而eax=0,接下來程式中A就開始不斷的執行
6. 怎麼打出B
前面是進程A開始不斷的打A了,而該怎麼交替的列印A和B?
要想列印B,那麼必須需要B這個進程執行,也就是得切換B進程對應的PCB,而切換的程式和上面的一樣,schedule、switch_to,那麼現在需要一個調用,也就是調用到schedule的入口,這個就是調度點,由於是交替列印A和B,那麼這個調度點該放到什麼位置合適呢?
需要中斷,時鐘中斷
也就是對於A來說,先執行一會,當前的counter=0就調用schedule,和上面一樣,也是通過switch_to,把對應的數據進行交換,然後B執行
何為交替?還是中斷,因為時鐘中斷已經做好了,每過一段時間就要做一次時鐘中斷
這個時候A和B就交替的出現了