fork函數

  複製進程映像:使用fork函數獲得的子進程從父進程繼承了整個進程的地址空間,包括:進程上下文、進程堆棧、內存信息、打開的文件描述符、信號控制設置、進程
優先級、進程組號當前工做目錄、根目錄、資源限制、控制終端等。
  函數

  子進程與父進程的區別在於:
1、父進程設置的鎖,子進程不繼承(例如對於一個排他鎖,父進程設置了鎖,子進程再設置,顯然不合適)
2、各自進程ID和父進程ID不一樣
3、子進程的未決警告被清除
4、子進程的未決信號集設置爲空集
 #include <unistd.h>this

#include <sys/types.h>spa

 pid_t   fork(void);//無參數,失敗返回-1。兩次返回是在各自的地址空間中返回的
A 進程fork進入內核 

孤兒進程:父進程先於子進程退出,託孤給init進程
殭屍進程:子進程先退出,父進程還未查詢子進程的退出狀態,子進程就處於僵死狀態(defunct)。指針

 

爲什麼父進程返回值大於0(新進程ID號碼),子進程返回0:由於子進程PCB中保存有進程ID和父進程ID,全部即使返回0,子進程也能獲取這兩個值;但父進程若返回0,則它code

沒法得知新建立的子進程的ID。blog

fork一次調用兩次返回(是在各自的進程地址空間中返回的),fork成功,意味着建立了一個進程副本,兩個進程。fork陷入內核,拷貝父進程代碼,因此子進程也有fork,並返回。繼承

 1 #include<unistd.h>
 2 #include<sys/types.h>
 3 #include<stdlib.h>
 4 #include<stdio.h>
 5 #include<errno.h>
 6 #include<string.h>
 7 #include<signal.h>
 8 #define ERR_EXIT(m)\
 9     do\
10     {\
11         perror(m);\
12         exit(EXIT_FAILURE);\
13     }while(0)  //宏要求一條語句
14 
15 int main()
16 {
17     signal(SIGCHLD,SIG_IGN);//避免僵死進程
18     printf("before fork pid=%d\n",getpid());
19     pid_t pid;
20     pid=fork();//進程代碼段、數據段、堆棧段等同樣,新進程的堆棧段和PCB也跟父進程同樣,因此下一條指令地址也同樣,因此不會從開頭運行。因此進程分支在fork以後。
21     if(pid==-1)
22         ERR_EXIT("fork error");
23     if(pid>0)
24     {
25         printf("this is parent pid=%d, child pid=%d\n",getpid(),pid);
26     }
27         
28     else if(pid==0)
29     {
30         //sleep(5);//父進程先結束
31         printf("this is child pid=%d, parent pid=%d\n",getpid(),getppid());
32     }
33         
34     return 0;
35 }
36 /*
37 子進程先結束
38 before fork pid=48714
39 this is parent pid=48714, child pid=48715
40 this is child pid=48715, parent pid=48714
41 */

   fork函數陷阱:1-->2-->4-->8  (核心:fork開始,會有兩個進程執行相同代碼段)進程

#include<unistd.h>
#include<sys/types.h>
#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
#define ERR_EXIT(m)\
    do\
    {\
        perror(m);\
        exit(EXIT_FAILURE);\
    }while(0)  //宏要求一條語句
int main()
{
    fork();
    fork();
    fork();
    printf("ok\n");
    return 0;
/*8
ok
ok
ok
ok
ok
ok
ok
ok
*/
}

 

  寫時複製(copy   on  write):內存

若是多個進程要讀取(僅僅讀取)它們本身的那部分資源的副本,那麼複製是沒必要要的(好比代碼段),每一個進程只要保存一個指向這個資源的指針就能夠了。若是一個進程要修改本身那份資源的副本,那麼就會複製那份資源。這就是寫時複製。資源須要修改纔要複製。其餘進程仍然共享。實際上不會被修改的數據是共享的。資源

相關文章
相關標籤/搜索