【作業系統】如何建立子程序?
實驗環境:Linux Fedora13
需要用到的命令:
top 動態檢視程序執行情況,包括殭屍程序的數量
ps 靜態檢視程序執行清情況
pstree 檢視程序樹
kill 清除一個正在執行的程序
./hello-loop.out& hello-loop.out是用gcc hello-loop.c後產生的檔案,前後加上 ./ 和 &以後使程序在後臺執行。
cat /proc/15485/maps 15485是PID號
第一列代表記憶體段的虛擬地址。
第二列代表執行許可權,r=可讀,w=可寫,x=可執行,p=私有 s=共享
第三列代表在程序地址裡的偏移量
第四列對映檔案的主裝置號和次裝置號
第五列映像檔案的節點號
第六列是映像檔案的路徑
首先我們可以看到hello-loop.out的程序有兩個
1. 08048000-08049000 r-xp 00000000 fd:00264898 /home/ root /hello-loop.out
2. 08049000-0804a000 rw-p 00000000 fd:00264898 /home/ root /hello-loop.out
我們可以看到第一個中的許可權是r-xp,第二個是rw-p
說明第一個是隻讀的,是程式碼段,而第二個是可讀寫的,是資料段。
需要了解的名詞:
PID 程序號
USER 使用者名稱
PR 核心排程優先順序
NI 程序優先順序(預設為0)
VIRT 程序“需要的”虛擬記憶體大小。
RES 程序使用的、未被換出的實體記憶體大小SHR共享記憶體
S 程序狀態
需要了解的函式:
fork()
呼叫fork()的當前程序作為父程序,建立一個子程序。父程序返回子程序的編號,子程序返回0。標頭檔案是unistd.h。
程式碼一 fork()入門:
#include<unistd.h> #include <stdio.h> int main(){ pid_t pid = fork(); if(pid>0){ //這裡是父程序 } else if(pid==0){ //這裡是子程序 } else{ //ERROR } }
1. 父程序首先執行到pid_t pid = fork()。
2. 此時並沒有子程序。
3. 然後父程序呼叫fork(),產生了一個子程序。
4. 此時有兩個程序在pid_t pid = fork();這一行上。
5. 然後父程序得到pid的值是子程序的PID號,而子程序的pid值是0。
6. 然後通過判斷pid的值,就可以把父程序和子程序區分開,呼叫不同的程式碼。
程式碼二:連續呼叫fork() (別執行)
#include <unistd.h>
#include <stdio.h>
int main(){
fork();
fork();
fork();
fork();
fork();
fork();
fork();
}
你會發現,程序數量呈細胞分裂的速度增長。
原因:
1. 呼叫第一個fork()的時候產生一個子程序,總共兩個程序。
2. 呼叫第二個fork()產生兩個子程序,總共四個程序。
3. 產生四個子程序,共八個程序。
4. 產生八個子程序,共十六個程序。
……
程式碼三:一個父程序建立十個子程序。
#include <unistd.h>
#include <stdio.h>
int main(){
int i = - 1;
pid_t pid;
for(;++i<10;){
pid = fork();
if(pid == -1){
}
else if(pid == 0){
while(1){
}
}
else{
}
}
while(1){
}
return 0;
}
程式碼四:建立一個連結串列型的十個子程序
#include <unistd.h>
#include <stdio.h>
int main(){
int i = - 1;
pid_t pid;
pid = fork();
for(;++i<9;){
if(pid == 0){
pid = fork();
continue;
}
else if(pid>0){
while(1){
}
}
}
return 0;
}
Fedora13用個+號來省略接下來的程序。
程式碼五:建立二叉樹型的十五個程序
#include <unistd.h>
#include <stdio.h>
int sum = 0;
void ts(){
if(sum<3){
sum++;
pid_t pid = fork();
if(pid == 0){
ts();
}
else if(pid > 0){
pid = fork();
if(pid == 0){
ts();
}
}
}
}
int main(int argc, char **argv){
ts();
while(1){}
return 0;
}
孤兒程序:
一個三個結點的二叉樹,一個父節點帶著兩個子節點,把父節點kill掉,兩個子節點會跑到init那裡。這兩個子節點就是孤兒程序。
殭屍程序:
父節點停止,子節點休眠,孫節點沒事做(Zombie)。