Linuxc高級編程之進程2

1.打印字符串“hello world!”
2.
在打印字符串“hello world!”前調用三次fork,
3.分析打印結果。


源代碼:

#include <stdio.h>
#include <unistd.h>
#include<stdlib.h>
int main()
{
    fork(); // 會產生兩個進程分支
    fork();// 前面產生的兩個進程每個都會產生兩個進程,有四個進程
    fork();// 前面產生的4個進程都會產生兩個進程,總共有八個進程
    printf("hello world!\n");// 八個進程所以會打印八次
return 0;
}

所用函數:
1.fork函數
一個進程可以調用fork函數創建一個新進程
新進程被稱爲子進程
函數原型
pid_t fork(void);
返回值
fork函數調用一次,但是返回兩次
在子進程中返回0,在父進程中返回子進程ID,出錯返回-1
通過返回值,可以確定是在父進程還是子進程中
子進程和父進程繼續執行fork調用之後的指令
子進程是父進程的副本
子進程獲得父進程數據空間、堆和棧的副本
父子進程並不共享這些存儲空間
父子進程共享正文段(只讀的)
爲了提高效率,fork後不併立即複製父進程空間,採用了COW(Copy-On-Write)
當父子進程任意之一,要修改數據段、堆、棧時,進行復制操作,但僅複製修改區域
fork()過程
調用alloc_task_struct(  )函數爲新進程分配8KB的task_struct空間和系統堆棧空間。
 讓當前指針指向父進程的task_struct ,並把父進程task_struct的內容拷貝到子進程的task_struct中。
檢查新創建這個子進程後,當前用戶所擁有的進程數目是否超出給他分配的資源的限制。
接下來,子進程的狀態被設置爲TASK_UNINTERRUPTIBLE以保證它不會馬上投入運行。
調用get_pid()爲新進程獲取一個有效的PID。
更新不能從父進程繼承的task_struct的其他所有域,例如,進程間親屬關係的域。
把新的task_struct插入進程鏈表,以確保進程之間的親屬關係。
把新的task_struct插入pidhash哈希表。
把子進程task_struct中的狀態域設置成TASK_RUNNING,並調用wake_up_process(  )把子進程插入到運行隊列鏈表。
讓父進程和子進程平分剩餘的時間片。
返回子進程的PID,這個PID最終由用戶態下的父進程讀取


fork函數常見用法:
一個父進程希望複製自己,使父子進程同時執行不同的代碼段
網絡服務程序中,父進程等待客戶端的服務請求,當請求達到時,父進程調用fork,使子進程處理該次請求,而父進程繼續等待下一個服務請求到達
一個進程要執行一個不同的程序
子進程從fork返回後,立即調用exec執行另外一個程序

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章