【Linux系统】06 进程概念

目录

​编辑

[1 冯・诺依曼体系结构](#1 冯・诺依曼体系结构)

[2 操作系统 (OS) 定位](#2 操作系统 (OS) 定位)

[2.1 广义与狭义操作系统](#2.1 广义与狭义操作系统)

[2.2 OS 两大目标](#2.2 OS 两大目标)

[2.3 系统调用 & 库函数](#2.3 系统调用 & 库函数)

[3 进程基础概念 & PCB (task_struct)](#3 进程基础概念 & PCB (task_struct))

[3.1 什么是进程](#3.1 什么是进程)

[3.2 PCB task_struct(Linux 的进程控制块)](#3.2 PCB task_struct(Linux 的进程控制块))

[3.3 查看进程的两种方式](#3.3 查看进程的两种方式)

[3.4 获取 PID、PPID 系统调用](#3.4 获取 PID、PPID 系统调用)

[4 fork () 创建子进程](#4 fork () 创建子进程)


1 冯・诺依曼体系结构

现代计算机(PC、服务器)均遵循冯诺依曼体系,五大部件:输入设备、存储器、CPU (运算器 + 控制器)、输出设备。

⚠关键点:这里的存储器指内存

  1. CPU只能直接读写内存,不能直接访问外设(键盘、显示器、硬盘);
  2. 外设和 CPU 之间的数据交互,必须经过内存中转;
  3. 所有设备数据交互都要和内存打交道。

拓展存储层次:寄存器 → L1/L2/L3 高速缓存 → 内存 DRAM → 本地磁盘 → 远程网络存储。速度逐级变慢,容量逐级变大。

思考题:QQ 聊天数据流向:键盘输入 → 内存 → CPU 处理 → 内存 → 网卡发送;接收消息:网卡收到数据到内存,CPU 处理,内存把数据输出到显示器。

2 操作系统 (OS) 定位

2.1 广义与狭义操作系统

  • 狭义 OS:内核 Kernel,四大核心模块:进程管理、内存管理、文件管理、驱动管理。
  • 广义 OS = 内核 + shell 外壳 + 标准库 + 系统工具软件。

2.2 OS 两大目标

  1. 向下:管理计算机全部软硬件资源;
  2. 向上:给上层应用程序提供安全、稳定的运行环境。

操作系统本质就是一款管理软件。 管理的实现思路两步:

  1. 描述 :用struct结构体把被管理对象的全部属性描述出来;
  2. 组织:用链表 / 红黑树等数据结构把这些结构体对象组织起来。

类比学校管理学生:学生信息用结构体描述,用链表把全部学生信息组织起来。

2.3 系统调用 & 库函数

内核不允许用户程序直接访问,内核向外暴露接口叫做系统调用。 系统调用接口功能底层,使用门槛高;标准库(libc)会对系统调用做封装,形成库函数。

用户程序 → 库函数 → 系统调用 → 内核 → 硬件。

3 进程基础概念 & PCB (task_struct)

3.1 什么是进程

  • 课本概念:程序的一次执行实例,正在运行的程序。
  • 内核视角:进程是分配系统资源(CPU 时间、内存)的基本实体。
  • 真实理解: 进程 = 内核数据结构PCB(task_struct) + 磁盘加载进来的程序代码和数据

程序:磁盘上静态的可执行文件;进程:内存中正在运行的实例,一个程序可以生成多个进程。

3.2 PCB task_struct(Linux 的进程控制块)

Linux 内核中,每一个进程对应一个task_struct结构体,存放在内存中,保存进程全部属性。

task_struct 核心成员:

  1. 标识符:PID 进程 ID,PPID 父进程 ID,用来唯一标识进程;
  2. 进程状态:运行、睡眠、僵尸等状态,退出码、退出信号;
  3. 优先级:决定 CPU 调度先后;
  4. 程序计数器:下一条要执行指令的地址;
  5. 内存指针 :指向该进程虚拟地址空间mm_struct;
  6. 上下文数据:CPU 寄存器的值;进程被切走的时候保存寄存器,恢复运行时回填;
  7. I/O 信息:进程打开的文件列表;
  8. 记账信息:CPU 使用时长统计。

内核把所有进程的task_struct用双向链表组织管理。

3.3 查看进程的两种方式

  1. /proc伪文件系统:内核把进程信息导出成目录,/proc/PID查看指定进程;

  2. 用户命令:

    ps aux #查看系统全部进程
    ps axj
    top #动态监控进程资源

3.4 获取 PID、PPID 系统调用

头文件 <sys/types.h> <unistd.h>

复制代码
getpid();   // 获取自己进程PID
getppid();  // 获取父进程PID

4 fork () 创建子进程

pid_t fork(); 创建子进程。

  1. 调用一次,返回两次;
  2. 父进程返回子进程 PID ;子进程返回0 ;出错返回 -1;
  3. 子进程以父进程为模板创建,代码共享,数据写时拷贝。
cpp 复制代码
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
    pid_t ret = fork();
    if(ret < 0)
    {
        perror("fork");
        return 1;
    }
    else if(ret == 0)
    {
        printf("子进程 pid:%d\n", getpid());
    }
    else
    {
        printf("父进程 pid:%d 子pid:%d\n",getpid(), ret);
    }
    sleep(1);
    return 0;
}

重点疑问:为什么一个函数会有两个返回值? fork 内核做两件事:创建子进程 task_struct、拷贝页表;fork 在子进程准备完毕之后,父子两个进程都会从 fork 返回处继续执行,所以得到两个返回值。 一般配合if‑else做父子进程业务分流。

相关推荐
2402_882893861 小时前
Linux 进程概念详解(上)—— 从冯诺依曼体系到僵尸进程与孤儿进程
linux·运维·服务器
qetfw1 小时前
Debian iptables 防火墙:默认拒绝、SNAT 与 DNAT 验证
linux·服务器·debian·php
忆挽篱笙歌2 小时前
冯诺依曼+操作系统+进程
linux·ubuntu
Apipi*3 小时前
30天速通Linux 第九章Linux网络编程
linux·运维·网络
报错小能手3 小时前
Channel面试题。Sync面试题
linux·服务器·windows
xiaoqiMikko3 小时前
Linux 实战(五):DNS、hosts、CLOSE-WAIT、SSH 权限与改端口 —— 三台真机实测
linux·centos
Linux-lucky3 小时前
43-Linux学习之旅之Shell 脚本(二)
linux·运维·学习·ubuntu·dash
yv798an3 小时前
从 OpenSBI 引导到 C++17 异步运行时:自制 RISC-V 嵌入式专有 NAS 踩坑全记录
linux
不悔哥4 小时前
Linux系统编程多线程程序如何安全退出
linux