0

0

【玩转Linux】如何快速理解进程概念

蓮花仙者

蓮花仙者

发布时间:2025-06-19 15:32:25

|

679人浏览过

|

来源于php中文网

原创

冯诺依曼体系结构

我们常见的计算机,如笔记本电脑,以及不常见的计算机,如服务器,大部分都遵循冯诺依曼体系结构。

【玩转Linux】如何快速理解进程概念截至目前,我们所认识的计算机,都是由一个个的硬件组件组成的。

输入单元:包括键盘、鼠标、扫描仪、写板等。
中央处理器(CPU):包含运算器和控制器等。
输出单元:显示器、打印机等。

关于冯诺依曼体系结构,必须强调几点:

  • 这里的存储器指的是内存。
  • 不考虑缓存情况,这里的CPU只能对内存进行读写,不能直接访问外设(输入或输出设备)。
  • 外设(输入或输出设备)要输入或者输出数据,也只能写入内存或者从内存中读取。
  • 一句话,所有设备都只能直接与内存打交道。

操作系统(Operator System)概念

任何计算机系统都包含一个基本的程序集合,称为操作系统(OS)。笼统地理解,操作系统包括:

  • 内核(进程管理、内存管理、文件管理、驱动管理)。
  • 其他程序(例如函数库、shell程序等)。

设计OS的目的是与硬件交互,管理所有的软硬件资源,为用户程序(应用程序)提供一个良好的执行环境。操作系统在整个计算机软硬件架构中的定位是一款纯正的“搞管理”的软件。

如何理解“管理”?

管理的例子描述被管理对象,组织被管理对象。

【玩转Linux】如何快速理解进程概念

进程基本概念

课本概念:程序的一个执行实例,正在执行的程序等。

内核观点:担当分配系统资源(CPU时间、内存)的实体。

描述进程-PCB

进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。课本上称之为PCB(process control block),Linux操作系统下的PCB是:task_struct。

task_struct-PCB的一种

在Linux中描述进程的结构体叫做task_struct。task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。

task_struct内容分类

  • 标示符:描述本进程的唯一标示符,用来区别其他进程。
  • 状态:任务状态、退出代码、退出信号等。
  • 优先级:相对于其他进程的优先级。
  • 程序计数器:程序中即将被执行的下一条指令的地址。
  • 内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针。
  • 上下文数据:进程执行时处理器的寄存器中的数据。
  • I/O状态信息:包括显示的I/O请求、分配给进程的I/O设备和被进程使用的文件列表。
  • 记账信息:可能包括处理器时间总和、使用的时钟数总和、时间限制、记账号等。
  • 其他信息。

组织进程可以在内核源代码里找到它。所有运行在系统里的进程都以task_struct链表的形式存在内核里。

查看进程

进程的信息可以通过/proc系统文件夹查看。

AdsGo AI
AdsGo AI

全自动 AI 广告专家,助您在数分钟内完成广告搭建、优化及扩量

下载

【玩转Linux】如何快速理解进程概念

通过系统调用获取进程标示符

进程ID(PID)和父进程ID(PPID)。

#include 
#include 
#include 
int main(){
    printf("pid: %d\n", getpid());
    printf("ppid: %d\n", getppid());
    return 0;
}

通过系统调用创建进程-fork

初识运行man fork,认识fork。fork有两个返回值,父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝)。

#include 
#include 
#include 
int main(){
    int ret = fork();
    printf("hello proc : %d!, ret: %d\n", getpid(), ret);
    sleep(1);
    return 0;
}

fork之后通常要用if进行分流。

#include 
#include 
#include 
int main(){
    int ret = fork();
    if(ret == 0){
        //子进程
    }else if(ret > 0){
        //父进程
    }else{
        //错误处理
    }
    return 0;
}

进程状态

/** The task state array is a strange "bitmap" of
 * reasons to sleep. Thus "running" is zero, and
 * you can test for combinations of others with
 * simple bit tests.
 */
static const char * const task_state_array[] = {
    "R (running)", /* 0 */
    "S (sleeping)", /* 1 */
    "D (disk sleep)", /* 2 */
    "T (stopped)", /* 4 */
    "t (tracing stop)", /* 8 */
    "X (dead)", /* 16 */
    "Z (zombie)", /* 32 */
};
  • R运行状态(running):并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。
  • S睡眠状态(sleeping):意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠interruptible sleep)。
  • D磁盘休眠状态(Disk sleep),有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。
  • T停止状态(stopped):可以通过发送SIGSTOP信号给进程来停止(T)进程。这个被暂停的进程可以通过发送SIGCONT信号让进程继续运行。
  • X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。

进程状态查看

ps aux / ps axj 命令

【玩转Linux】如何快速理解进程概念

Z(zombie)-僵尸进程

僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程(使用wait()系统调用,后面讲)没有读取到子进程退出的返回代码时就会产生僵死(尸)进程。僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态。

来一个创建维持30秒的僵死进程例子:

#include 
#include 
int main(){
    pid_t id = fork();
    if(id > 0){
        //父进程
        printf("parent[%d] is sleeping...\n", getpid());
        sleep(30);
    }else{
        printf("child[%d] is begin Z...\n", getpid());
        sleep(5);
        exit(EXIT_SUCCESS);
    }
    return 0;
}

僵尸进程危害

进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),你交给我的任务,我办的怎么样了。可父进程如果一直不读取,那子进程就一直处于Z状态?是的!维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说,Z状态一直不退出,PCB一直都要维护?是的!那一个父进程创建了很多子进程,就是不回收,是不是就会造成内存资源的浪费?是的!因为数据结构对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间!内存泄漏---

进程状态总结

孤儿进程

父进程如果提前退出,那么子进程后退出,进入Z之后,那该如何处理呢?父进程先退出,子进程就称之为“孤儿进程”。孤儿进程被1号init进程领养,当然要有init进程回收喽。

#include 
#include 
#include 
int main(){
    pid_t id = fork();
    if(id > 0){
        //父进程
        printf("parent[%d] is exiting...\n", getpid());
        exit(EXIT_SUCCESS);
    }else{
        //子进程
        printf("child[%d] is sleeping...\n", getpid());
        sleep(30);
        exit(EXIT_SUCCESS);
    }
    return 0;
}

【玩转Linux】如何快速理解进程概念

学习编程就得循序渐进,扎实基础,勿在浮沙筑高台。

相关专题

更多
if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

770

2023.08.22

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

220

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

190

2025.07.04

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

536

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

17

2025.12.22

深入理解算法:高效算法与数据结构专题
深入理解算法:高效算法与数据结构专题

本专题专注于算法与数据结构的核心概念,适合想深入理解并提升编程能力的开发者。专题内容包括常见数据结构的实现与应用,如数组、链表、栈、队列、哈希表、树、图等;以及高效的排序算法、搜索算法、动态规划等经典算法。通过详细的讲解与复杂度分析,帮助开发者不仅能熟练运用这些基础知识,还能在实际编程中优化性能,提高代码的执行效率。本专题适合准备面试的开发者,也适合希望提高算法思维的编程爱好者。

24

2026.01.06

磁盘配额是什么
磁盘配额是什么

磁盘配额是计算机中指定磁盘的储存限制,就是管理员可以为用户所能使用的磁盘空间进行配额限制,每一用户只能使用最大配额范围内的磁盘空间。php中文网为大家提供各种磁盘配额相关的内容,教程,供大家免费下载安装。

1373

2023.06.21

如何安装LINUX
如何安装LINUX

本站专题提供如何安装LINUX的相关教程文章,还有相关的下载、课程,大家可以免费体验。

705

2023.06.29

c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

58

2026.01.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 7.8万人学习

Git 教程
Git 教程

共21课时 | 3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号