当前位置:首页 > 系统教程 > 正文

手撕Linux进程核心!(从PCB到fork,带你吃透进程本质与实操)

手撕Linux进程核心!(从PCB到fork,带你吃透进程本质与实操)

手撕Linux进程核心!(从PCB到fork,带你吃透进程本质与实操) Linux进程控制块  fork系统调用 进程生命周期 Linux进程调度 第1张

欢迎来到Linux系统编程第十二讲!今天我们将深入Linux进程管理的核心,从进程控制块(PCB)到fork系统调用,彻底搞懂进程的本质。无论你是小白还是有一定基础,这篇教程都会带你轻松上手。

1. 什么是进程?

进程是程序的一次执行实例,是操作系统资源分配的基本单位。每个进程都有独立的地址空间、代码、数据和打开的文件。在Linux中,进程的一生经历了进程生命周期的多个阶段:创建、运行、等待、终止等。

2. 进程控制块(PCB)—— task_struct

Linux内核使用Linux进程控制块(即 task_struct 结构体)来管理每个进程。这个结构体包含了进程的所有信息:

  • 进程标识符(PID):唯一标识进程。
  • 进程状态:运行、就绪、阻塞、僵尸等。
  • 优先级和调度信息:用于Linux进程调度
  • 内存管理指针:指向进程地址空间。
  • 文件描述符表:打开的文件。
  • 上下文信息:寄存器、堆栈等。

PCB是进程存在的唯一证据,内核通过它感知和控制进程。

3. fork系统调用——创建新进程

fork系统调用是Linux中创建进程的核心方法。它通过复制调用进程(父进程)创建一个新的子进程。fork函数原型:

    #include pid_t fork(void);  

fork调用一次,返回两次:

  • 在父进程中返回子进程的PID。
  • 在子进程中返回0。
  • 如果出错返回-1。

fork采用写时拷贝技术,提高效率。子进程可以继承父进程的代码、数据、堆栈等,但拥有独立的地址空间。

4. 实操:动手写一个fork示例

下面是一个简单的C程序,演示进程创建:

    #include #include int main() {    pid_t pid = fork();    if (pid < 0) {        perror("fork failed");        return 1;    } else if (pid == 0) {        printf("子进程:PID=%d, 父进程PPID=%d", getpid(), getppid());    } else {        printf("父进程:PID=%d, 子进程PID=%d", getpid(), pid);    }    return 0;}  

编译运行,你会看到两个进程输出不同的信息。这正是Linux进程管理的精髓。

5. 进程生命周期与状态变迁

通过fork创建后,子进程进入就绪态,等待调度。运行中可能因等待资源进入睡眠态,终止后进入僵尸态,直到父进程回收。理解进程生命周期有助于编写健壮的程序。

总结

本文从Linux进程控制块开始,到fork系统调用,结合进程生命周期Linux进程调度,全面解析了进程核心。希望你能动手实践,深入理解!