可以執行一次、多次或同時執行的一組指令和數據稱為程序。該過程是這樣一個程序的執行。因此,這些進程可以運行許多程序。在同一個進程中,操作系統可以加載不同的程序。當前目錄、權限、文件句柄等重用的進程狀態將被新程序繼承。這與 fork()、exec()、wait()、exit() 等系統調用在同一級別完成。
本文詳細介紹了Linux系統調用fork()、exec()、wait()、exit()的例子和用法示例。
叉()
fork() 是 Linux/Unix 系統上最特殊和最有用的系統調用之一。該進程使用它來創建一個作為自身副本的進程。這樣的系統調用允許父進程創建子進程。直到子進程執行完畢,父進程才會被中斷。
下面是 fork() 的一些亮點:
- 父進程獲取具有非零值的子進程 ID。
- 零值返回給孩子。
- 如果在創建子進程時出現系統或硬件錯誤,則返回-1 給fork()。
- 子進程獲取的唯一進程ID與現有進程組的ID不匹配。
為了詳細說明fork(),我們來看一個闡明fork()概念的例子。
$ sudo vim fork.c
複製和粘貼的代碼是:
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/types.h> int main(int argc, char **argv) { pid_t pid; pid = fork(); if(pid==0) { printf("It is the child process and pid is %dn",getpid()); exit(0); } else if(pid > 0) { printf("It is the parent process and pid is %dn",getpid()); } else { printf("Error while forkingn"); exit(EXIT_FAILURE); } return 0; }
輸出:
$make fork
當我運行腳本時,我得到了下面屏幕截圖中顯示的結果。
$ ./fork
嵌入 ()
exec() 是一個系統調用,它通過用新的進程映像替換當前進程映像來工作。但是,原來的進程還是新的,只是新的進程替換了頭數據、棧數據等等。通過將程序加載到當前進程空間來從入口點運行程序。
為了解釋細節,讓我們看一下下面顯示的示例。
$ sudo vim exec.c
代碼如下:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/wait.h> main(void) { pid_t pid = 0; int status; pid = fork(); if (pid == 0) { printf("I am the child."); execl("/bin/ls", "ls", "-l", "/home/ubuntu/", (char *) 0); perror("In exec(): "); } if (pid > 0) { printf("I am the parent, and the child is %d.n", pid); pid = wait(&status); printf("End of process %d: ", pid); if (WIFEXITED(status)) { printf("The process ended with exit(%d).n", WEXITSTATUS(status)); } if (WIFSIGNALED(status)) { printf("The process ended with kill -%d.n", WTERMSIG(status)); } } if (pid < 0) { perror("In fork():"); } exit(0); }
輸出:
$ make exec
當我運行腳本時,我得到了下面屏幕截圖中顯示的結果。
$ ./exec
等待()
與 fork 一樣,創建並執行子進程,但父進程暫停,直到子進程執行。在這種情況下,暫停父進程會自動激活 wait() 系統調用。當子進程完成執行時,父進程重新獲得控制權。
為了詳細說明wait(),我們用一個例子來說明wait()系統調用。
$ sudo vim wait.c
這是一個代碼示例:
#include<stdio.h> // printf() #include<stdlib.h> // exit() #include<sys/types.h> // pid_t #include<sys/wait.h> // wait() #include<unistd.h> // fork int main(int argc, char **argv) { pid_t pid; pid = fork(); if(pid==0) { printf("It is the child process and pid is %dn",getpid()); int i=0; for(i=0;i<8;i++) { printf("%dn",i); } exit(0); } else if(pid > 0) { printf("It is the parent process and pid is %dn",getpid()); int status; wait(&status); printf("Child is reapedn"); } else { printf("Error in forking..n"); exit(EXIT_FAILURE); } return 0; }
輸出:
$ make wait
當我運行腳本時,我得到了下面屏幕截圖中顯示的結果。
$ ./wait
出口 ()
exit() 就是這樣一個函數,或者用於退出進程的系統調用。這個系統調用定義了線程執行的完成,尤其是在多線程環境中。捕獲過程的狀態以供將來參考。
使用exit()系統調用後,操作系統取回進程使用的所有資源,操作系統退出進程。系統調用Exit()等價於exit()。
概括
#include <unistd.h> void _exit(int status); #include <stdlib.h> void _Exit(int status);
您可以在上面的 fork() 和 wait() 示例中看到如何使用 exit() 函數。 使用 exit() 系統調用退出進程。
結論是
在本文中,我們通過一些示例詳細了解了 fork()、exec()、wait() 和 exit() 系統調用。有關更多信息,請使用這些系統調用運行程序並查看結果。謝謝你!