一、複製進程映像
1、fork函數介紹
此系統調用主要複製當前進程,在進程表中建立一個新的表項,新表項中的許多屬性與當前進程是相同的。新進程幾乎與原進程一模一樣,執行的代碼也完全相同,但新進程有自己的資料空間、環境和檔案描述符。
2、典型使用fork的程式碼片段:
pid_t pid;pid = fork();switch(pid){case -1: // error occur perror("fork failed"); exit(1);case 0: // child break;default: // parent break;}
3、樣本
範例程式碼:
View Code
#include <sys/types.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>int main(){ pid_t pid; char *message; int n; printf("fork program starting \n"); pid = fork(); switch(pid) { case -1: perror("fork failed"); exit(1); case 0: message = "This is the child"; n = 5; break; default: message = "This is the parent"; n = 3; break; } for(;n>0;n--) { puts(message); sleep(1); } exit(0);}
運行效果如下:
二、替換進程映像
1、exec系列函數介紹
exec系列函數可以把當前進程替換為一個新的進程,函數列表如下:
int execl(const char *path, const char *arg, ...);int execlp(const char *file, const char *arg, ...);int execle(const char *path, const char *arg,..., char * const envp[]);int execv(const char *path, char *const argv[]);int execvp(const char *file, char *const argv[]);int execvpe(const char *file, char *const argv[],char *const envp[]);
2、標頭檔:
#include <unistd.h>
3、樣本
範例程式碼:
#include <unistd.h>#include <stdio.h>#include <stdlib.h>int main(){ execlp("ls","ls","-l",0); printf("OK\n"); exit(0);}
運行效果:
三、啟動新進程
1、system函數實現
1.1 說明
system函數可以在一個程式的內部啟動另一個程式,從而建立一個新進程。
#include <stdlib.h>int system(const char *string);
system函數的作用是,運行以字串參數的形式傳遞給它的命令並等待該命令的完成。命令的執行情況就如同在shell中執行如下命令:
$sh -c string
1.2 樣本
範例程式碼:
#include <stdlib.h>#include <stdio.h>int main(){ system("ls -l"); printf("OK\n"); exit(0);}
運行效果:
2、fork和exec系列函數實現
一般來說,使用system函數不是啟動其它進程的理想手段,因為它必須用一個shell來啟動需要的程式。由於啟動之前需要先啟動一個shell,而且對shell的安裝情況及使用的環境的依賴也很大,所以使用system函數效率不高。鑒於此種情況,可以考慮使用fork啟動子進程,然後用exec系列函數替換當前子進程滿足此種需求。
範例程式碼(wait1.c):
#include <sys/types.h>#include <sys/wait.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>int main(){ pid_t pid; char *message; int exit_code; printf("fork program starting\n"); pid = fork(); switch(pid) { case -1: perror("fork failed"); exit(1); case 0: message = "This is the child"; sleep(3); //sleep execlp("ls","ls","-l",0); exit_code = 37; break; default: message = "This is the parent"; exit_code = 0; break; } if(pid != 0) //wait child { int stat_val; pid_t child_pid; child_pid = wait(&stat_val); printf("Child has finished : PID = %d\n",child_pid); if(WIFEXITED(stat_val)) printf("Child exited with code %d\n",WEXITSTATUS(stat_val)); else printf("Child terminated abnormally\n"); } exit(exit_code);}
運行效果: