linux手冊中詳細地描述了每個系統呼叫,感興趣的話可以參考。
linux中每個程序都有乙個唯一的正數程序id,通過getpid
以及getppid
可以得到呼叫程序的pid以及其父程序的pid。
#include
#include
pid_t getpid
(void);
pid_t getppid
(void);
// 返回:呼叫者或其父程序的pid
程序可以呼叫exit
函式終止自己,status
表示程序的退出狀態,從主程式返回乙個數值同樣可以設定程式的退出狀態。
#include
exit
(int status)
;// 該函式不返回
父程序通過呼叫fork
函式建立乙個新的執行的子程序。
#include
#include
pid_t fork
(void);
// 返回:子程序返回0,父程序返回子程序的pid,如果出錯,則為-1
fork
函式建立出的新程序會得到與父程序相同的使用者級虛擬位址空間,包括**、資料段、堆、共享庫以及使用者佔,也會獲得相同的開啟的檔案描述符的副本。fork
函式也非常令人迷惑,它只被呼叫一次,卻返回兩次,一次在父程序中(返回子程序pid),一次在子程序中(返回0)。因為父程序中的返回值總是不為0(子程序pid或-1),因此可以以此判斷程式是在父程序還是子程序中執行。呼叫fork
的程式往往有如下特點:
int
main()
上述**中,第乙個fork
被父程序執行,建立了乙個子程序child_1;第二個fork
被父程序和子程序child_1執行,建立了子程序child_2以及子程序child_3,因此共建立了三個子程序,加上乙個父程序共四個程序。其輸出結果如下:
hello world!
hello world2!
hello world2!
hello world3!
hello world3!
hello world3!
hello world3!
終止的子程序需要被父程序**,否則會成為僵死(zombie)程序。父程序終止時,init
程序(所有程序的祖先)會成為其未結束或**的孤兒程序的養父。若父程序未**其僵死程序就終止,那麼init
程序會**它。即便僵死程序沒有執行,它也會消耗系統資源,因此長時間執行的程式總是應當**它的僵死程序。乙個程序通過呼叫waitpid
函式燈帶它的子程序終止或停止:
#include
#include
pid_t waitpid
(pid_t pid,
int*statusp,
int options)
;pid_t wait
(int
*statusp)
;// 等價於 waitpid(-1, &status, 0)
// 返回:若成功**,則為子程序pid,如果 wnohang,則為0,其它錯誤,則為-1
pid 指定等待集合成員
pid>0,等待集合是乙個pid=pid的子程序
pid=-1,等待集合是其所有子程序
statusp 檢查已**子程序的退出狀態,包括wifexited wexitstatus wifsignaled
等多個值,見參考。
options 可以用來修改函式行為,這些選項可以通過或運算組合起來
wnohang 若等待集合中的任何子程序都未終止,那麼立即返回
wuntraced 掛起呼叫程序,若等待集合中的乙個程序終止或停止,則返回其pid
wcontinued 掛起呼叫程序,直到等待集合中乙個正在執行的程序終止或等待集合中乙個被停止的程序收到sigcont
訊號重新執行。
#include
unsigned
intsleep
(unsigned
int secs)
;// 返回:剩下的要休眠的秒數
intpause
(void);
// 返回:-1
sleep
函式會掛起當前程序直到時間到或者被訊號中斷,而pause
則掛起程序直到程序收到乙個訊號。
execve
函式在當前程序上下文載入並執行乙個新程式,與fork
不一樣,該函式呼叫成功後從不返回:
#include
intexecve
(const
char
*filename,
const
char
*ar**,
const
char
*envp)
;// 如果成功,則不返回,如果錯誤,返回-1
引數中的ar**
表示待執行程式的命令列引數,envp
表示環境變數,與waitpid
一樣,該函式也有許多版本,詳細資訊可以參考(execve)[如下**展示了使用fork
在子程序中通過execve
呼叫linux下ps
命令(程式未包含錯誤處理,僅供參考):
#include
#include
#include
#include
intmain()
;char
*nenv=
;execve
("/bin/ps"
, nar**, nenv)
;// execve不返回,控制流不會到這裡
printf
("!!!this printf will not run!!!");
}// 休眠等待子程序執行
sleep(2
);if(pid ==
waitpid(-
1,null,0
))printf
("child process: %ld recycled, exit now...\n",(
long
)pid)
;return0;
}
上述程式的輸出:
this process will run ps -ef in child process:
uid pid ppid c stime tty time cmd
root 1 0 0 21:31 ? 00:00:00 /init
root 7 1 0 21:31 tty1 00:00:00 /init
eric 8 7 0 21:31 tty1 00:00:00 -bash
eric 94 8 0 22:40 tty1 00:00:00 ./a.sh
eric 95 94 0 22:40 tty1 00:00:00 /bin/ps -ef
child process: 95 recycled, exit now...
可以看到,pid為94的程序建立了子程序95,並在子程序中執行了/bin/ps -ef
命令列印出了系統中的程序資訊。
本文講述了linux中程序控制較為基本的函式,這些函式能夠用來建立、休眠、終止、**程序等。程序控制往往需要與訊號(signal)以及程序間通訊(ipc interprocess communication)如訊息佇列等配合使用,相關部落格也會在接下來的學習過程中寫一寫。
linux 程序控制
什麼是程序 每乙個程序在系統中都有唯一的id標示它,此id為程序標示符 程序標示符的型別 pit t,其實是乙個無符號整形 乙個程序標示符對應唯一的乙個程序,多個程序標示符可以對應同乙個程式 程序和程式的區別 程式 可執行的二進位制 檔案,這種檔案載入到記憶體中執行就得到了乙個程序 程序 同乙個程式...
Linux程序控制
linux程序控制 獲取pid include include pid t getpdi void 獲取本程序id pdi t getppid vodi 獲取父程序id,及獲取建立子程序的程序id 程序建立 include pid t fork void 建立子程序 呼叫一次返回兩次值 1.父程序中...
linux程序控制
linux程序控制 編寫命令直譯器 一 背景 之前在 計算機作業系統 這本書中已經多次接觸了程序這一概念,而程序在作業系統中具體是做什麼的呢?卻沒有實際的與程序發生過互動,因此也就沒有實際的感受。對於我來說程序僅僅停留在概念的層面上 程序是程式執行時的記憶體空間和設定或者說程序就是程式的進行時。沒有...