程序的建立
1.詳解程序建立的幾類函式的說明:
fork
,vfork
,exec
,system?
(1)獲取id
#include
#include
pid_t getpid(void) 獲取本程序id。
pid_t getppid(void) 獲取父程序id
(2)啟動程序
(a)pid_tfork(void)
功能:建立子程序
fork的奇妙之處在於它被呼叫一次,卻返回兩次,
它可能有三種不同的返回值:
0: 子程序
子程序id(大於0):父程序
-1: 出錯
例項:
#include
#include
intmain()
說明:
v 在pid=fork()之前,只有乙個程序在執行,但在這條語句執行之後,就變成兩個程序在執行了,這兩個程序的共享**段,將要執行的下一條語句都是if(pid==0).
v 兩個程序中,原來就存在的那個程序被稱作「父程序」,新出現的那個程序被稱作「子程序」,父子程序的區別在於程序識別符號(pid)不同.
(b)pid_t vfork(void)
功能:建立子程序
表頭檔案: #include
定義函式: pid_t vfork(void);
函式說明: v
vfork()
會產生乙個新的子程序,其子程序會
複製父程序的資料與堆疊空間,並繼承父程序的使用者**,組**,環境變數、已開啟的檔案**、工作目錄和資源限制等。 v
子程序不會繼承父程序的檔案鎖定和未處理的訊號。 v
注意,linux不保證子程序會比父程序先執行或晚執行,因此編寫程式時要留意死鎖或競爭條件的發生。
(c)exec函式族
exec
用被執行的程式替換呼叫它的程式。
區別:
fork
建立乙個新的程序,產生乙個新的pid。
exec
啟動乙個新程式,替換原有的程序,因此程序的pid不會改變
更多詳情見博文——exec函式族 2.
舉例對比
fork
,vfork
的區別,函式出現位置的不同能否區分**出現的原因?
區別:
(1)fork:子程序拷貝父程序的資料段
vfork:
子程序與父程序共享資料段
(2)fork:父、子程序的執行次序不確定
vfork:
子程序先執行,父程序後執行
(a)fork函式
#include
#include
intmain(void)
輸出:
count = 1
count = 1
count++
被父程序、子程序一共執行了兩次,為什麼count的第二次輸出為什麼不為2?
v子程序的資料空間、堆疊空間都會從父程序得到乙個拷貝,而不是共享。
v 在子程序中對count進行加1的操作,並沒有影響到父程序中的count值,父程序中的count值仍然為0
(b)vfork函式
#include
#include
int main(void)
輸出:
count = 1
count = 2
思考
:如何新建立乙個程序
,然後執行乙個程式?
程序的等待
1.
殭屍程序的**?如何避免?
如果乙個程序在其終止的時候,自己就**所有分配給它的資源,系統就不會產生所謂的殭屍程序了。
v 父程序呼叫fork建立子程序後,子程序執行直至其終止,它立即從記憶體中移除,但程序描述符仍然保留在記憶體中(程序描述符占有極少的記憶體空間)。
v 子程序的狀態變成exit_zombie,並且向父程序傳送sigchld
訊號,父程序此時應該呼叫
wait()
系統呼叫來獲取子程序的退出狀態以及其它的資訊。在 wait 呼叫之後,殭屍程序就完全從記憶體中移除。
v 因此乙個殭屍存在於其終止到父程序呼叫wait 等函式這個時間的間隙,一般很快就消失,但如果程式設計不合理,父程序從不呼叫 wait 等系統呼叫來收集殭屍程序,那麼這些程序會一直存在記憶體中。
避免:
一、讓殭屍程序的父程序來**,父程序每隔一段時間來查詢子程序是否結束並**,呼叫wait()或者waitpid(),通知核心釋放殭屍程序。
二、採用訊號sigchld通知處理,並在訊號處理程式中呼叫wait函式。
三、讓殭屍程序變成孤兒程序,由init**,就是讓父親先死。
2.
wait
和waitpid
的用法,兩者什麼時候是相等的?掌握不同情況下的引數和返回值
wait
函式的作用: 程序的等待,阻塞程序,等待某個子程序退出;
函式的原型: pid_t wait(int *status);
返回值:成功返回子程序pid,出錯-1;
waitpid
函式的作用:等待退出,等待訊號,或者指定的程序結束
函式的原型:pid_t waitpid(pid_t pid , int *status, intoptions);
函式的引數:
pid <-1 :等待程序的pid絕對值的任何的子程序;
pid=-1, 任何子程序,---等於wait;
pid=0,
pid >0, 等待子程序為pid的子程序退出
options:
wnohang:如果沒有子程序退出,馬上返回不等待
wuntraced:如果子程序進入暫停執**況,馬上返回,
返回值:如果執行成功返回的是子程序的pid,失敗-1;
如果使用wnohang的時候,沒有子程序退出,
程序的退出
1.
掌握exit
和_exit
的異同點,在核心中有什麼區別?舉例論證
exit
,_exit用於終止程序
區別:
_exit:
直接使程序停止,清除其使用的記憶體,並清除緩衝區中內容
exit
與 _exit的區別:在停止程序之前,要檢查檔案的開啟情況,並把檔案緩衝區中的內容寫回檔案才停止程序。
exit()
:正常結束程序
表頭檔案: #include
定義函式: void exit(int status);
函式說明:
exit()
用來正常終結目前程序的執行,並把引數status返回給父程序,而程序所有的緩衝區資料會自動寫回並關閉未關閉的檔案。
_exit()
:結束程序執行
表頭檔案: #include
定義函式: void _exit(int status);
函式說明:
_exit()
用來立刻結束目前程序的執行,並把引數status返回給父程序,並關閉未關閉的檔案。
此函式呼叫後不會返回,並且會傳遞sigchld訊號給父程序,父程序可以由wait函式取得子程序結束狀態。
2.
掌握return
,exit
等退出程序的異同點
return
與exit()
均可用於函式的返回,但
return
只是本函式的返回,而
exit()
則是整個程式的退出。
Linux程序 程序的建立
今天學習了linux的程序建立的基本原理,是基於0.11版本核心的。下面對其作一下簡單的總結。一 linux程序在記憶體中的相關資源 很容易理解,linux程序的建立過程就是記憶體中程序相關資源產生的過程,那麼linux程序在記憶體中有哪些相關資源呢?1 task陣列中的一項 乙個指標指向程序的ta...
程序的建立
fork 用來建立新的程序 在父程序中返回子程序的程序號,在子程序中返回0,錯誤返回 1 表頭檔案 include include 定義函式 pid t fork void pid t 建立程序時會用到程序號的型別定義,實際上為int型別 在fork 建立乙個程序的同時,子程序完全複製父程序的資源,...
程序建立多少執行緒,程序建立的過程,執行緒建立的過程
程序能建立多少執行緒與程序邏輯位址空間 32位位址長度的話,就是4gb 更具體地說應該是有程序位址空間中記憶體對映區的大小有關,執行緒棧是通過mmap系統呼叫在記憶體對映區建立的。和執行緒棧 1mb 的大小有關。程序建立的過程 unix和linux採用另一種方式 它把建立程序分成兩步,fork 和e...