
程序建立與終止
到目前為止,我們知道每當我們執行一個程式時,就會建立一個程序,並在執行完成後終止。如果我們需要在程式中建立一個程序,並可能希望為它安排不同的任務,該怎麼辦?這可以實現嗎?是的,顯然可以透過程序建立來實現。當然,任務完成後,它會自動終止,或者您可以根據需要終止它。
程序建立是透過**fork()系統呼叫**實現的。新建立的程序稱為子程序,啟動它的程序(或開始執行的程序)稱為父程序。fork()系統呼叫之後,我們現在有兩個程序——父程序和子程序。如何區分它們?很簡單,透過它們的返回值。

建立子程序後,讓我們看看fork()系統呼叫的細節。
#include <sys/types.h> #include <unistd.h> pid_t fork(void);
建立子程序。此呼叫之後,存在兩個程序,現有的程序稱為父程序,新建立的程序稱為子程序。
fork()系統呼叫返回以下三個值之一:
負值表示錯誤,即建立子程序不成功。
子程序返回零。
父程序返回一個正值。此值是新建立子程序的程序 ID。
讓我們考慮一個簡單的程式。
File name: basicfork.c #include <stdio.h> #include <sys/types.h> #include <unistd.h> int main() { fork(); printf("Called fork() system call\n"); return 0; }
執行步驟
編譯
gcc basicfork.c -o basicfork
執行/輸出
Called fork() system call Called fork() system call
**注意**——通常在fork()呼叫之後,子程序和父程序將執行不同的任務。如果需要執行相同的任務,則對於每個fork()呼叫,它將執行2的n次方次,其中**n**是fork()呼叫的次數。
在上述情況下,fork()呼叫一次,因此輸出列印兩次(2的1次方)。如果fork()呼叫,例如3次,則輸出將列印8次(2的3次方)。如果呼叫5次,則列印32次,依此類推。
在瞭解了fork()如何建立子程序之後,現在是時候瞭解父程序和子程序的詳細資訊了。
檔名:pids_after_fork.c
#include <stdio.h> #include <sys/types.h> #include <unistd.h> int main() { pid_t pid, mypid, myppid; pid = getpid(); printf("Before fork: Process id is %d\n", pid); pid = fork(); if (pid < 0) { perror("fork() failure\n"); return 1; } // Child process if (pid == 0) { printf("This is child process\n"); mypid = getpid(); myppid = getppid(); printf("Process id is %d and PPID is %d\n", mypid, myppid); } else { // Parent process sleep(2); printf("This is parent process\n"); mypid = getpid(); myppid = getppid(); printf("Process id is %d and PPID is %d\n", mypid, myppid); printf("Newly created process id or child pid is %d\n", pid); } return 0; }
編譯和執行步驟
Before fork: Process id is 166629 This is child process Process id is 166630 and PPID is 166629 Before fork: Process id is 166629 This is parent process Process id is 166629 and PPID is 166628 Newly created process id or child pid is 166630
程序可以透過以下兩種方式之一終止:
異常終止,發生在傳遞某些訊號時,例如終止訊號。
正常終止,使用_exit()系統呼叫(或_Exit()系統呼叫)或exit()庫函式。
_exit()和exit()之間的主要區別在於清理活動。**exit()**在返回控制給核心之前會執行一些清理工作,而**_exit()**(或_Exit())會立即將控制返回給核心。
考慮以下帶有exit()的示例程式。
檔名:atexit_sample.c
#include <stdio.h> #include <stdlib.h> void exitfunc() { printf("Called cleanup function - exitfunc()\n"); return; } int main() { atexit(exitfunc); printf("Hello, World!\n"); exit (0); }
編譯和執行步驟
Hello, World! Called cleanup function - exitfunc()
考慮以下帶有_exit()的示例程式。
檔名:at_exit_sample.c
#include <stdio.h> #include <unistd.h> void exitfunc() { printf("Called cleanup function - exitfunc()\n"); return; } int main() { atexit(exitfunc); printf("Hello, World!\n"); _exit (0); }
編譯和執行步驟
Hello, World!