linux 進程的建立

1. 進程號:linux

  每一個進程在被初始化的時候,系統都會爲其分配一個惟一標識的進程id,稱爲進程號;shell

  進程號的類型爲pid_t,經過getpid()和getppid()能夠獲取當前進程號和當前進程的父進程的進程號;數據結構

2. 進程複製:函數

  fork函數,是以父進程爲藍本複製一個新的子進程,包括複製代碼段,數據段,堆棧段等,除了代碼段,子進程會有本身的物理內存空間,其中的內容是和父進程的數據段,堆棧段是同樣的,固然進程號是不同;spa

  在linux下,fork函數是用寫複製實現的。所謂寫複製,只複製父進程的虛擬地址空間(數據結構),子進程並不會產生本身的物理內存空間,直到父進程或者子進程中有對某個段的寫行爲的時候,再爲子進程建立獨立的物理內存控制。寫複製的目的是爲了提供建立進程的效率;code

  fork函數在父進程中調用一次,返回兩次。根據返回值的不一樣判斷是在父進程仍是在子進程中執行。父進程返回的是子進程的進程號,子進程返回的是0,若是失敗返回-1;blog

3. system函數:進程

  建立新的進程調用shell命令,並阻塞當前進程直到shell命令執行完成;內存

  不能執行返回127,成功返回進程狀態值,失敗返回-1;資源

int ret = system("ping www.baidu.com");

4. exec函數族:

  exec函數會建立新的進程,並替換當前進程的資源,所以新的進程號依然和原來的進程號相同;

  exec函數在執行之後不會返回,由於新的進程資源已經佔據了當前進程的資源,包括代碼段,數據段和堆棧段等,只有進程調用失敗才返回-1;

  exec函數一般會在fork以後,在新的子進程中被調用,這樣的話,新的進程會佔用子進程的資源進行運行;

  linux系統採用寫時複製,在fork以後若是當即調用exec函數,不會當即複製父進程的資源,而是使用exec的參數來覆蓋原有進程。除非發生了原來的內存內容發生改變時,才建立新的物理內存空間;

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char **arg) {
    pid_t pid = getpid();
    pid_t ppid = getppid();
    printf("linux net: %d %d \n", pid, ppid);

    pid_t cpid = fork();
    int count = 1;
    if (cpid > 0) {
         printf("parent progress: %d %d %d. %d \n", cpid, getpid(), getppid(), count);
         count = 111;
    }
    else if (cpid == 0) {
        printf("child progress: %d %d %d. %d \n", cpid, getpid(), getppid(), count);
        count = 222;

        int ret = execvp("./net-exe-test", 0);
        printf("exec ret %d \n", ret);
    }
    else {
        printf("create progress failed. \n");
    }
    printf("---------------------1 pid %d count %d \n", getpid(), count);
    getchar();

    return 0;
}
相關文章
相關標籤/搜索