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

Linux进程控制入门教程(从零开始掌握进程创建与退出)

Linux进程控制入门教程(从零开始掌握进程创建与退出)

基础概念与核心操作详解

Linux系统编程中,进程控制是每一位开发者必须掌握的核心技能。进程是程序运行的实例,系统通过进程来管理和调度任务。本文将带你从零开始,深入理解Linux下的进程创建进程退出以及相关的僵尸进程等概念,并通过实例帮助你建立扎实的基础。

Linux进程控制入门教程(从零开始掌握进程创建与退出) 进程控制 进程创建 进程退出 僵尸进程 第1张

一、什么是进程?

进程是一个正在执行的程序实例,它拥有独立的地址空间、代码、数据和系统资源。当你运行一个命令或启动一个应用程序时,系统就会创建一个对应的进程。每个进程都由一个唯一的标识符——进程ID(PID)来区分,同时还会记录它的父进程ID(PPID)。理解进程是学习进程控制的第一步。

二、进程的创建——fork() 系统调用

Linux中创建新进程最常用的方法是使用 fork() 系统调用。它会创建一个与父进程几乎完全相同的子进程。子进程会复制父进程的代码、堆栈、数据段,并拥有自己的PID。调用 fork() 后,父子进程各自独立运行,返回值用于区分父子进程:在父进程中返回子进程的PID,在子进程中返回0,如果出错则返回-1。

#include #include int main() {    pid_t pid = fork();  // 关键:进程创建    if (pid == 0) {        printf("这是子进程,PID:%d", getpid());    } else if (pid > 0) {        printf("这是父进程,子进程PID:%d", pid);    } else {        perror("fork失败");    }    return 0;}

通过这个例子,你能直观地看到进程创建的过程。运行程序后,父子进程会分别打印信息,且输出的顺序不确定,这取决于内核的调度。

三、进程的退出——exit() 与 _exit()

进程在完成工作后需要进程退出,释放占用的资源。常用的退出函数有 exit()_exit()

  • exit() 是标准C库函数,会先执行用户注册的退出清理函数(如 atexit),刷新I/O缓冲区,最后调用内核的 _exit()
  • _exit() 是系统调用,直接终止进程,不进行任何清理操作。
#include #include #include void cleanup() {    printf("执行退出清理函数");}int main() {    atexit(cleanup);  // 注册退出函数    printf("程序即将退出");    exit(0);  // 进程退出,会调用cleanup    // _exit(0);  // 直接退出,不调用cleanup}

理解两种退出方式的区别,有助于你编写更健壮的代码,避免资源泄漏。

四、僵尸进程与孤儿进程

当子进程先于父进程退出,但父进程没有调用 wait()waitpid() 来获取子进程的退出状态时,子进程的进程描述符仍然保留在系统中,这种状态称为僵尸进程。僵尸进程不占用CPU和内存,但会占据内核进程表项,大量僵尸进程会导致系统无法创建新进程。

另一种情况是父进程先退出,子进程还在运行,此时子进程成为孤儿进程。孤儿进程会被init进程(PID=1)收养,由init负责回收资源,因此不会造成危害。

// 模拟僵尸进程int main() {    pid_t pid = fork();    if (pid == 0) {        printf("子进程退出,但父进程未等待");        exit(0);  // 子进程退出,变成僵尸    } else {        sleep(60);  // 父进程睡眠,此时子进程已是僵尸        printf("父进程结束");    }    return 0;}

避免僵尸进程的方法是让父进程调用 wait()waitpid() 来回收子进程,这部分内容我们将在下篇详细讲解。

五、总结与下篇预告

本文介绍了Linux进程控制的基础:进程的概念、进程创建(fork)、进程退出(exit/_exit)以及僵尸进程的产生原因。掌握这些是深入学习进程间通信、多线程编程的基石。在下篇中,我们将继续探讨进程等待(wait/waitpid)、进程替换(exec族函数)等高级话题,帮助你全面掌握Linux进程控制。

—— 持续学习,深入理解Linux内核 ——