进程概念【linux】

简介: 进程概念【linux】

进程基础

在学习进程之前,首先要有一定的计算机硬件和软件基础。

硬件基础:冯·诺依曼体系结构

如图,是计算机在硬件上的体系结构。

下面举出一些常见的输入输出设备(有些设备只作输出设备,或者只作输入设备;而有些设备既能作为输出设备,又能作为输入设备)

输入设备:话筒、摄像头、键盘、网卡、磁盘,鼠标等等

输出设备:声卡、显卡、网卡、磁盘、显示器,打印机等等

这些设备连接在一起的目的:设备之间的数据流动。本质是设备之间频繁的数据拷贝!所以说,对数据进行拷贝的整体速度,是决定计算机效率的重要指标

经典场景:程序在运行的时候,必须把程序先加载到内存。

程序文件里都是指令和数据,这些指令和数据最终是要让 CPU 来执行的,而程序文件在生成后会存储在磁盘中,磁盘中的文件要先加载到内存,才能和 CPU 进行交互。所以,程序在运行的时候,必须先将程序加载到内存。

软件基础:操作系统

操作系统是计算机上一个进行软硬件资源管理的软件,同时它也是计算机开机同时第一个被加载的软件,它可以为用户提供一个稳定、高效、安全的运行环境

管理:根据数据做决策(操作系统)

被管理:执行管理者的决策(软硬件)

计算机对数据管理的建模:先将堆数据的管理场景转化为对特定数据结构的增删查改,将具体问题,转化为计算机级别的建模,先描述,再组织

那么到底什么是进程呢?

用程序来举例子,一个可执行程序的本质是二进制文件,保存在磁盘中,在运行时要将程序先加载到内存中;计算机上的软件,如微信,qq,本质上也是一个.exe的可执行程序,在启动时都要先加载到内存中。

这些可执行程序,在被加载到内存中后,就会变成一个个进程!

加载到内存后,如何对这些进程进行管理呢?

对每一个进程,都由一个 内核PCB 和 可执行程序 组成,这个内核PCB也被称为进程控制块(process ctrl block)。

这个内核PCB可以看做一个结构体,这个结构体中包含进程的状态、优先级、标识符、内存指针等包含进程信息的所有属性字段。对进程的管理,可以看做对每一个进程PCB的管理,所有对进程的控制和操作,都只与进程的PCB有关,与进程的可执行程序无关!

总结:对进程的管理,可以粗略的看做在多个PCB对象形成的链表中,对一个个结点进行增删查改

几乎所有的指令,都是程序,加载到内存运行起来后也要变成进程。CPU的主要工作就是在内存中取指令 -> 分析指令 -> 执行指令 这个周期内进行循环。

CPU中也存在着一个 存储器PC ,PC里的指令指针 IP/EIP等存储正在执行指令的下一条指令的地址,指令指针指向哪一个进程的代码,就表示哪一个进程即将调度!判断、循环、函数跳转指令的本质,就是修改储存器PC里的指令指针指向。

进程状态

创建一个进程的,系统中就多了一个进程!在Linux中普通进程都有它的父进程,每个进程都会有一个编号叫 pid ,每次启动进程的 pid 几乎都会变化,因为这个进程是全新的进程!

下面代通过 父进程创建子进程的过程 来测试新创建的进程

fork()函数,头文件 #include<unistd.h>

fork()函数用来创建子进程,有两个返回值,给子进程返回0,给父进程返回子进程的id。(在Linux中,可以用同一个变量名,表示不同的内存)

#include<stdio.h>                                                                                                           
 #include<unistd.h>
 #include<stdlib.h>
 #include<sys/types.h>
 #include<sys/wait.h>
 int main()
 {
   pid_t id = fork();
   if(id == 0){
       printf("我是子进程,my_pid:%d,my_ppid:%d,return id:%d\n",getpid(),getppid(),id);
       exit(0);
   }
   else{
       printf("我是父进程,my_pid:%d,my_ppid:%d,return id:%d\n",getpid(),getppid(),id);
   }
 }

子进程被创建,其实是以父进程为模板的:子进程会将父进程的字段信息浅拷贝过来,利用写时拷贝(写的时候再进行开空间深拷贝,否则就浅拷贝)来优化创建进程的效率。

运行结果:

一个进程崩溃了,是否会影响其他进程的运行?

仅从运行上来说是不会的,任意进程之间具有独立性,互相不影响。

测试:父进程崩溃了,是否会影响子进程的运行?

#include<stdio.h>                                                                                                                   
  #include<unistd.h>
  #include<stdlib.h>
  #include<sys/types.h>
  #include<sys/wait.h>
  int main()
  {
    pid_t id = fork();
    while(1)
    {
      if(id==0)
      {
  
        printf("我是子进程,my_pid:%d,my_ppid:%d,return id:%d\n",getpid(),getppid(),id);
        sleep(1);
      }
      else
      {
         printf("我是父进程,my_pid:%d,my_ppid:%d,return id:%d\n",getpid(),getppid(),id);
         sleep(1);
      }
    }
    return 0;
  }

使用 kill -9 指令杀死父进程

可以看到杀死父进程后,子进程依然还在运行,但它的 ppid 发生了改变,变成了‘孤儿进程’。

进程排队

就算进程放在了CPU上,进程也不会是一直在运行的!

CPU中有时间片的概念,即CPU会给当前进程分配一个时间片的时间(极短)来运行,后面的进程按开启时间顺序进行排队,一旦时间片上的时间耗尽,当前进程依然没有运行结束,CPU就会进行切换进程,未完成的进程继续入队,等待下一次调度。这种方式公平、高效,可以有效防止进程阻塞或者挂起而造成CPU资源的浪费!

宏观上来看,我们可以同时打开多个软件,仿佛有很多程序在同时运行。但是实际上,CPU每次只能处理一个进程的内容,只是轮换的时间极短,我们没有发现而已。

进程阻塞

上面提到了进程阻塞的概念,那么进程阻塞一般是什么样的场景呢?

如我们运行一个C语言程序,在程序启动的那一刻,就被加载到内存上,形成了一个进程。这个程序中有需要使用者用键盘输入的部分,但使用者迟迟没有输入。在等待的这段过程中,这个进程看似在运行中,但CPU不可能一直等待着使用者输入。这时候进程就会将自己设置为阻塞状态,根据不同的阻塞类型排入不同的等待队列进行排队,等待软件或硬件资源就绪后再继续运行。

所以总结下来:当进程在等待软硬件资源的时候,且资源没有就绪,进程就会将自己设置为阻塞状态,处于阻塞状态的进程会根据等待资源的不同而被连入多个等待队列中!

进程挂起

当计算机资源吃紧的时候,操作系会对一些优先级不高的进程设置为挂起状态,并将其移到外存,等到条件允许了再将这个进程调回内存中。

僵尸进程

每一个进程的创建都是为了完成某些用户需要的工作的,所以这些进程必须有结果、有数据(进程状态)。进程退出后,它的这些进程状态还需要它自己维持住,供上层读取。

当某个进程死亡(退出)后,它的进程状态没有被他的父进程读取,那这个进程目前的状态,就是僵尸状态。僵尸状态的进程,会一直存在,内存得不到释放,会造成内存泄漏!

孤儿进程

一个进程的父进程先于子进程死亡(退出),那这个子进程就会被1号进程过领养,变成一个孤儿进程。

相关文章
|
10天前
|
算法 Linux 调度
深入理解Linux操作系统的进程管理
本文旨在探讨Linux操作系统中的进程管理机制,包括进程的创建、执行、调度和终止等环节。通过对Linux内核中相关模块的分析,揭示其高效的进程管理策略,为开发者提供优化程序性能和资源利用率的参考。
33 1
|
5天前
|
SQL 运维 监控
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具
|
14天前
|
调度 开发者
核心概念解析:进程与线程的对比分析
在操作系统和计算机编程领域,进程和线程是两个基本而核心的概念。它们是程序执行和资源管理的基础,但它们之间存在显著的差异。本文将深入探讨进程与线程的区别,并分析它们在现代软件开发中的应用和重要性。
33 4
|
13天前
|
运维 监控 Linux
Linux操作系统的守护进程与服务管理深度剖析####
本文作为一篇技术性文章,旨在深入探讨Linux操作系统中守护进程与服务管理的机制、工具及实践策略。不同于传统的摘要概述,本文将以“守护进程的生命周期”为核心线索,串联起Linux服务管理的各个方面,从守护进程的定义与特性出发,逐步深入到Systemd的工作原理、服务单元文件编写、服务状态管理以及故障排查技巧,为读者呈现一幅Linux服务管理的全景图。 ####
|
1月前
|
缓存 监控 Linux
linux进程管理万字详解!!!
本文档介绍了Linux系统中进程管理、系统负载监控、内存监控和磁盘监控的基本概念和常用命令。主要内容包括: 1. **进程管理**: - **进程介绍**:程序与进程的关系、进程的生命周期、查看进程号和父进程号的方法。 - **进程监控命令**:`ps`、`pstree`、`pidof`、`top`、`htop`、`lsof`等命令的使用方法和案例。 - **进程管理命令**:控制信号、`kill`、`pkill`、`killall`、前台和后台运行、`screen`、`nohup`等命令的使用方法和案例。
128 4
linux进程管理万字详解!!!
|
18天前
|
缓存 算法 Linux
Linux内核的心脏:深入理解进程调度器
本文探讨了Linux操作系统中至关重要的组成部分——进程调度器。通过分析其工作原理、调度算法以及在不同场景下的表现,揭示它是如何高效管理CPU资源,确保系统响应性和公平性的。本文旨在为读者提供一个清晰的视图,了解在多任务环境下,Linux是如何智能地分配处理器时间给各个进程的。
|
29天前
|
存储 运维 监控
深入Linux基础:文件系统与进程管理详解
深入Linux基础:文件系统与进程管理详解
70 8
|
26天前
|
网络协议 Linux 虚拟化
如何在 Linux 系统中查看进程的详细信息?
如何在 Linux 系统中查看进程的详细信息?
50 1
|
26天前
|
Linux
如何在 Linux 系统中查看进程占用的内存?
如何在 Linux 系统中查看进程占用的内存?
|
1月前
|
算法 Linux 定位技术
Linux内核中的进程调度算法解析####
【10月更文挑战第29天】 本文深入剖析了Linux操作系统的心脏——内核中至关重要的组成部分之一,即进程调度机制。不同于传统的摘要概述,我们将通过一段引人入胜的故事线来揭开进程调度算法的神秘面纱,展现其背后的精妙设计与复杂逻辑,让读者仿佛跟随一位虚拟的“进程侦探”,一步步探索Linux如何高效、公平地管理众多进程,确保系统资源的最优分配与利用。 ####
70 4