到目前為止,我們知道每當執行一個程式時,就會建立一個進程,並在執行完成後終止。 如果我們需要在程式中建立一個進程,並且可能希望為其安排不同的任務。 這可以實現嗎? 是的,顯然是通過進程建立來實現。 當然,工作完成後進程會自動終止,或者根據需要終止。
過程建立是通過fork()
系統呼叫實現的。 新建立的進程稱為子進程,啟動該進程的進程(或執行開始時的進程)稱為父進程。 在fork()
系統呼叫之後,現在有兩個進程 - 父進程和子進程。 如何區分它們? 非常簡單,可通過它們的返回值來區分它們。
在建立子進程之後,讓我們看看fork()
系統呼叫細節。參考以下程式碼 -
#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
建立子進程。 這個呼叫之後,有兩個進程,現有的進程稱為父進程,新建立的進程稱為子進程。
fork()
系統呼叫返回三個值之一 -
讓我們來看看一個簡單的程式。
// 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;
}
編譯 -
yiibai$ gcc basicfork.c -o basicfork
執行後輸出結果如下 -
Called fork() system call
Called fork() system call
註 - 通常在呼叫
fork()
之後,子進程和父進程將執行不同的任務。 如果需要執行相同的任務,那麼對於每個fork()
呼叫,它將執行n
次,其中n
是呼叫fork()
的次數。
在上面的情況下,fork()
被呼叫一次,因此輸出列印兩次(2次冪)。 如果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!