fork函數講解和運用(循環創建n個子進程)

作用
fork函數用於創建一個子進程
用法
#include <unistd.h>
pid_t fork(void);
對於父進程來說,fork函數返回成功返回子進程id,對於子進程來說,fork函數成功返回0;失敗返回-1;
C/C++中的函數返回值只能有一個,這裏看似兩個返回值,是因爲父進程執行到fork調用處,產生一個子進程,子進程擁有和父進程相同的代碼,但是父子進程從fork調用處繼續往下執行,所以父進程調用fork有一個返回值,子進程調用fork有一個返回值。此外,父子進程執行順序由調度器決定。
相關函數
getpid 獲取當前進程的進程id,getppid 獲取父進程的進程id;對於./a.out生產的這個進程,其父進程是bash
#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void);
pid_t getppid(void);
實例
循環創建n個子進程
由於父子進程執行順序由調度器決定,因此加上sleep()函數保證父進程最後結束

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main(void)
{
    int i;
    pid_t pid;
    printf("xxx\n");
    
    for(i = 0; i<5; i++){
        pid = fork();
        if(pid == -1){
            perror("fork error;");
            exit(1);
        }else if(pid == 0){
            break;
        }else{
            printf("parent\n");
        }
    }
    printf("===========pid = %u\n",pid);
    if(i < 5){
        sleep(i);
        printf("I am %d child , i=%d,pid = %u\n",i+1,i,getpid());
    }else{
        sleep(i);
        printf("I am parent\n");
    }
    return 0;
}

在這裏插入圖片描述
父子進程共享
fork之後,父子進程的異同
父子相同處:全局變量、.data、.text、棧、堆、環境變量、用戶ID、宿主目錄、進程工作目錄、信號處理
父子不同處:進程ID、fork返回值、父進程ID、進程運行時間、鬧鐘、未決信號集
父子進程共享:文件描述符(打開文件的結構體)、mmap建立的映射區(兩個進程建立mmap映射區實現通信)
雖然看似子進程的0~3G的虛擬地址空間中的用戶地址空間一樣,但是並不是每次fork出一個子進程,子進程就會把父進程的虛擬地址空間拷貝一份(早期linux設計是這樣的),而是遵循讀時共享寫時複製的原則

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