第八章 程序控制

2021-04-27 04:34:07 字數 2868 閱讀 2463

1 fork是核心建立新程序的唯一方法(除了交換程序,init和頁精靈程序)

2 子程序獲得父程序的資料空間,堆,棧。子程序的這些空間是父程序的拷貝,並不共享。子程序也會複製父程序的io快取(程式8.1的例子).但是很多實現並不做父程序資料段和堆的完全拷貝,有的使用了「寫時複製」的技術。

3 從下面的例子可以看到,子程序中變數的位址和父程序是一樣的。

#include

#include "ourhdr.h"

int glob = 6;

char buf = "a write to stdout/n";

int main()

else

sleep(2);

printf("pid=%d, glob=%d(%p), var=%d(%p)/n", getpid(), glob, &glob, var, &var);

exit(0);

}--------

結果:(父程序和子程序中兩個變數的位址是一樣的)

a write to stdout

before fork  

pid=32638, glob=7(0x80497a0), var=89(0xbfeb0484)

pid=32637, glob=6(0x80497a0), var=88(0xbfeb0484)

jl問題:在rh linux下執行兩次同乙個可執行檔案,可執行檔案對應程式中變數分配的位址是不同的,和別人請教的結果是我們的可執行檔案是shell的子程序,所需會分配shell所有的環境,可能由於shell的環境在兩次執行的時候不同,所以我們的可執行檔案裡面變數的位址也不同。

4 子程序同時獲得父程序的檔案描述符,然後,父子程序都可以操作檔案描述符所指向的檔案,修改其偏移量。(jl問題:假如父程序刪除了檔案,那麼子程序操作此檔案的時候就會出錯?還是系統不允許這麼做?)

5 父、子程序之間的區別是:

• fork的返回值。

• 程序i d。

• 不同的父程序i d。

• 子程序的t m s _ u t i m e , t m s _ s t i m e , t m s _ c u t i m e以及t m s _ u s t i m e設定為0。

• 父程序設定的鎖,子程序不繼承。

• 子程序的未決告警被清除。

• 子程序的未決訊號集設定為空集。

6 fork有兩種用法:

1)乙個父程序希望複製自己,使父、子程序同時執行不同的**段。這在網路服務程序中是常見的——父程序等待委託者的服務請求。當這種請求到達時,父程序呼叫f o r k,使子程序處理此請求。父程序則繼續等待下乙個服務請求。

jl問題:此時為何不用多執行緒?

2)乙個程序要執行乙個不同的程式。這對s h e l l是常見的情況。在這種情況下,子程序在從f o r k返回後立即呼叫e x e c

jl問題:此時exec是否又啟動乙個新的程序?如果是,為何需要fork之後再exec?不如直接exec. 需要往後看

7 vfork

1)用於建立乙個新程序,而該新程序的目的是e x e c乙個新程式

2)v f o r k與f o r k一樣都建立乙個子程序,但是它並不將父程序的位址空間完全複製到子程序中,因為子程序會立即呼叫e x e c (或e x i t ),於是也就不會存訪該位址空間。不過在子程序呼叫e x e c或e x i t之前,它在父程序的空間中執行。

這種工作方式在某些u n i x的頁式虛存實現中提高了效率

3)v f o r k和f o r k之間的另乙個區別是: v f o r k保證子程序先執行,在它呼叫e x e c或e x i t之後父進

程才可能被排程執行。

jl問題:書上說下面程式中如果用exit(0)來代替_exit(0),下面那個列印pid的就不能列印出來(因為vfork出的程序執行在父程序的空間裡面,exit會關閉父程序的io流,所以printf列印會出錯;而_exit只會退出,不會關閉io流,故printf可以列印出來),實際我在linux上執行的時候,無論用哪個都可以列印出來.why?

#include

#include "ourhdr.h"

int glob = 6;

int main()

else if(pid == 0)

printf("pid=%d, glob=%d, var=%d/n",getpid(), glob, var);

exit(0);

}8 wait waitpid

最後乙個要考慮的問題是:乙個由i n i t程序領養的程序終止時會發生什麼?它會不會變成乙個僵死程序?對此問題的回答是「否」,因為i n i t被編寫成只要有乙個子程序終止, i n i t就會呼叫乙個w a i t函式取得其終止狀態。這樣也就防止了在系統中有很多僵死程序。

jl問題:前面說到呼叫wait就會是程序阻塞,那麼init呼叫wait不會使init阻塞麼?init 也是乙個程序啊。。。

9 僵死程序:

子程序終止,但是父程序尚未對其作善後處理(獲取終止子程序的有關資訊、釋放它仍占用的資源)的程序。

如何避免終止程序?比如程序a和b,a是父,b是子。 可以讓a先fork乙個中間程序c,然後用c來fork乙個b,然後讓c先退出,那麼b就成為init的子程序。此時a和b同時執行,b不會成為僵死程序。

9 exec:

用f o r k函式建立子程序後,子程序往往要呼叫一種e x e c函式以執行另乙個程式。

當程序呼叫一種e x e c函式時,該程序完全由新程式代換,而新程式則從其m a i n函式開始執行。

因為呼叫e x e c並不建立新程序,所以前後的程序i d並未改變。e x e c只是用另乙個新程式替換了

當前程序的正文、資料、堆和棧段。

10 更改使用者i d和組i d

什麼是有效使用者id和有效組id?需要查資料。

11 waitpid的用法還沒有看到

第八章 程序控制

1.程序標示符pid id為1 的通常是 init 程序。在自舉過程中被核心呼叫。該程序的程式檔案時 sbin init。此程序負責在自舉核心後啟動乙個unix系統。讀與系統相關的初始化檔案 etc rc 或 etc inittab 以及 etc init.d中的檔案 並引導系統到乙個狀態 如多使用...

第八章 程序控制 waitpid函式

waitpid 等待子程序中斷或結束 表頭檔案 include include 定義函式 pid t waitpid pid t pid,int status,int options 函式說明 waitpid 會暫時停止目前程序的執行,直到有訊號來到或子程序結束。如果在呼叫 wait 時子程序已經結...

第八章 程序排程和時間

總體來講,對於作業系統而言,處理機在任意時刻只能執行乙個程序。linux系統的排程基於分時 time sharing 技術 多個程序以 時間多路復用 方式執行,cpu的時間被分成 片 slice 每個可執行程序可以分配一片。在linux中,與程序相關的引數用資料結構task struct來描述。在有...