作業系統---之fork()函式
【Linux】關於理解fork()函式的簡單例子
1.fork()函式
fork()函式通過系統呼叫建立一個與原來程式幾乎完全相同的程式,這個新產生的程式稱為子程式。一個程式呼叫fork()函式後,系統先給新的程式分配資源,例如儲存資料和程式碼的空間。然後把原來的程式的所有值都複製到新的新程式中,只有少數值與原來的程式的值不同。相當於克隆了一個自己。需要注意的一點:就是呼叫fork函式之後,一定是兩個程式同時執行的程式碼段是fork函式之後的程式碼,而之前的程式碼以及由父程式執行完畢。下面來看一個很簡單的例子。
fork函式返回兩個值
- 返回一個大於0的值給父程式
- 返回0給子程式
- 返回其他值說明fork失敗了
2.關於fork的一個簡單例子
#include<stdio.h>
#include<unistd.h>
int main()
{
pid_t pid;
int count = 0;
pid = fork(); //fork一個程式
if(pid == 0)
{ //pid為0,
printf("this is child process, pid is %d\n",getpid());//getpid返回的是當前程式的PID
count+=2;
printf("count = %d\n",count);
}
else if(pid > 0)
{
printf("this is father process, pid is %d\n",getpid());
count++;
printf("count = %d\n",count);
}
else
{
fprintf(stderr,"ERROR:fork() failed!\n");
}
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
下面是執行結果:
有人會對這個執行結果產生一種錯覺,就是程式中if語句的兩條分支if(pid == 0)和else if(pid > 0)都得到了執行,其實完全不是這麼回事,出現這種執行結果的原因是因為,在main()函式的第6行fork了一個程式,這個程式稱為原來程式的子程式,原來的那個程式稱為父程式,這個程式與原來的程式併發執行,誰先稅後沒有規律,由作業系統排程決定。
我們用gdb工具對這個程式單步執行除錯一下,可能會對這個過程瞭解的更清晰一些。
3.使用gdb除錯父程式。
1.輸入gdb a.out然後輸入start開始除錯,此時終端顯示即將執行的程式碼
2.輸入n,執行當前一行程式碼,同時顯示下一條將執行的程式碼
即將建立一個子程式,當前程式為父程式。
3.再輸入n執行pid=fork()語句
這個時候,終端上顯示
Detaching after fork from child process 2755.
this is child process, pid is 2755
count = 2
- 1
- 2
- 3
這個時候,說明已經新建了一個子程式,子程式PID是2755,而且由於我們現在單步除錯的是父程式,並不影響子程式的執行,這個子程式只有幾行程式碼,這個時候已經執行完了,並且在終端上顯示了執行結果,就是下面兩行內容。
this is child process, pid is 2755
count = 2
- 1
- 2
4.這個時候,我們輸入p pid看一下fork函式返回給父程式的值是不是子程式的PID
果然就是子程式的PID值。
5.輸入n接著執行判斷語句
由於pid的值為2755,因此跳過了if(pid==0)分支內的語句,轉而判斷pid是否大於0
6.輸入n接著判斷pid是否大於0
pid的值大於0,執行分支內的語句。
7.接著輸入n,直到程式正常結束
上面是父程式的除錯過程,其實子程式也可以用gdb來除錯,下次再說。
4.使用ps aux命令檢視父程式和子程式
ps aux命令可以檢視系統中正在執行的所有程式,不過我們這個例子程式碼很少,系統瞬間就能執行完畢,用ps aux命令根本捕捉不到。因此我們在程式碼中做一些修改。
#include<stdio.h>
#include<unistd.h>
int main()
{
pid_t pid;
int count = 0;
pid = fork(); //fork一個程式
if(pid == 0)
{ //pid為0,
printf("this is child process, pid is %d\n",getpid());
count+=2;
printf("count = %d\n",count);
}
else if(pid > 0)
{
printf("this is father process, pid is %d\n",getpid());
count++;
printf("count = %d\n",count);
}
else
{
fprintf(stderr,"ERROR:fork() failed!\n");
}
sleep(10);//新加入的行,讓程式在這裡暫停10秒,父程式和子程式都會執行這行程式碼
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
我們在第30行加入了一條語句,讓程式暫停10s
重新編譯程式,然後執行程式,輸入./a.out後,快速切換到另外一個終端(如果你手速慢的話,多暫停一會兒就可以),輸入ps aux檢視正在執行的程式。
執行程式:
切換終端,輸入ps aux檢視程式
可以看到a.out程式產生了兩個程式,父程式PID是2928,子程式PID是2929。
轉載:https://blog.csdn.net/ww1473345713/article/details/51708003
相關文章
- 研究linux函式 之 fork()Linux函式
- fork()與vfork()函式函式
- fork函式的學習--深入瞭解計算機系統函式計算機
- 作業系統(一)作業系統歷史:從標準函式庫到雲端計算作業系統函式
- 理解 pcntl_fork 函式函式
- 分散式作業管理系統 Asgard分散式
- 核心函式 系統呼叫 系統命令 庫函式函式
- 作業系統(1)——作業系統概述作業系統
- 作業系統(一):作業系統概述作業系統
- 第八講 函式作業函式
- 作業系統(二):作業系統結構作業系統
- 作業系統之程式管理:16、管程作業系統
- 寫作業系統之實現程式作業系統
- 作業系統 作業5作業系統
- 主流嵌入式作業系統有哪些?作業系統
- 作業系統2—作業系統概論(下)作業系統
- 作業系統1—作業系統概論(上)作業系統
- 《作業系統》作業系統
- [作業系統]作業系統
- 作業系統作業系統
- MySQL函式大全(字串函式,數學函式,日期函式,系統級函式,聚合函式)MySql函式字串
- Linux作業系統之Shell程式設計Linux作業系統程式設計
- 作業系統之排程演算法作業系統演算法
- Java作業系統課設之模擬程式管理系統Java作業系統
- 計算機作業系統|作業系統引論計算機作業系統
- 作業系統: Unix作業系統演進簡史作業系統
- 【多程式】Linux中fork()函式詳解|多程式Linux函式
- 作業系統-1.1_2作業系統四個特徵作業系統特徵
- 手機寫作業系統之 圖形模式作業系統模式
- Linux作業系統 程式之間的通訊Linux作業系統
- 計算機作業系統之程式掃盲計算機作業系統
- 寫作業系統之開發載入器作業系統
- 寫作業系統之搭建開發環境作業系統開發環境
- 作業系統原理作業系統
- Linux 作業系統Linux作業系統
- 作業系統概念作業系統
- NodeOS作業系統作業系統
- Linux作業系統Linux作業系統