可以執行一次、多次或同時執行的一組指令和數據稱為程序。該過程是這樣一個程序的執行。因此,這些進程可以運行許多程序。在同一個進程中,操作系統可以加載不同的程序。當前目錄、權限、文件句柄等重用的進程狀態將被新程序繼承。這與 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

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() 系統調用。有關更多信息,請使用這些系統調用運行程序並查看結果。謝謝你!