1. 创建进程
创建进程的核心操作是使用 fork()
系统调用。
1.1 fork()
系统调用
fork()
创建一个新进程(子进程),新进程几乎是父进程的完整拷贝。fork()
返回两次:
- 在父进程中,返回子进程的 PID。
- 在子进程中,返回 0。
#include <stdio.h>
#include <unistd.h>
int main() {
pid_t pid = fork(); // 创建一个新进程
if (pid == -1) {
// 错误处理:fork 失败
perror("fork failed");
return 1;
} else if (pid == 0) {
// 子进程代码
printf("This is the child process. PID: %d\n", getpid());
} else {
// 父进程代码
printf("This is the parent process. PID: %d, Child PID: %d\n", getpid(), pid);
}
return 0;
}
2. 进程终止
进程可以通过以下方式终止:
- 正常退出:调用
exit()
。 - 异常退出:调用
abort()
。
2.1 正常退出
exit()
函数用于正常终止进程并返回一个状态码给操作系统。状态码通常用来表示进程的退出状态。
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("Process is exiting normally.\n");
exit(0); // 正常退出,状态码为 0
}
2.2 异常退出
abort()
函数用于非正常退出进程,通常是由于程序错误。abort()
终止进程并产生核心转储(如果系统配置为生成核心转储)。
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("Process is aborting.\n");
abort(); // 异常退出
}
3. 进程结束后的处理
进程终止后,父进程可以使用 wait()
或 waitpid()
系统调用来回收子进程的资源,并获取子进程的退出状态。
3.1 wait()
系统调用
wait()
阻塞调用,直到子进程终止。它返回子进程的 PID,并将子进程的退出状态存储在一个整数中。
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
pid_t pid = fork();
if (pid == -1) {
perror("fork failed");
return 1;
} else if (pid == 0) {
// 子进程代码
printf("Child process is exiting.\n");
exit(42); // 子进程退出,状态码为 42
} else {
// 父进程代码
int status;
pid_t terminated_pid = wait(&status); // 等待子进程终止
if (WIFEXITED(status)) {
printf("Child process %d exited with status %d.\n", terminated_pid, WEXITSTATUS(status));
} else {
printf("Child process %d did not exit normally.\n", terminated_pid);
}
}
return 0;
}