Linux 进程

发布于:2024-05-24 ⋅ 阅读:(64) ⋅ 点赞:(0)

冯诺依曼体系

任何计算机系统都包含一个基本的程序集合,称为操作系统(OS)

  • 笼统的理解,操作系统包括:
  • 内核(进程管理,内存管理,文件管理,驱动管理)
  • 其他程序(例如函数库, shell程序等等)

在这里插入图片描述

操作系统

为什么要有操作系统

操作系统对下<手段>进行软硬件管理工作,对上层提供良好(稳定、安全、高效)的运行环境<目的>。

在这里插入图片描述

系统调用和库函数概念

在开发角度,操作系统对外会表现为一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分由操作系统提供的接口,叫做系统调用。

系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者可以对部分系统调用进行适度封装,从而形成库,有了库,就很有利于更

层用户或者开发者进行二次开发。

进程的组成

一个进程内包括 内核task_struct结构体+程序的代码和数据

如何理解进程动态运行

只要我们的进程task_struct,将来在不同的队列中,进程就可以访问不同的资源

系统调用接口和用户操作接口

系统调用接口是操作系统提供给用户程序的接口,用于请求操作系统内核提供的服务和功能。

用户操作接口是用户程序提供给用户自身或其他用户程序的接口,用于实现用户程序的功能和交互。

进程

PCB

  • 定义:PCB是操作系统中用于管理和维护进程信息的数据结构。每个进程都有对应的 PCB,用于存储进程的状态、优先级、程序计数器、内存分配情况、打开文件列表等信息。
  • 作用:PCB用于跟踪和管理进程的运行状态,操作系统通过维护 PCB 来管理进程的调度、资源分配和状态转换。
  • 内容:PCB 包含了进程的所有关键信息,如进程标识符(PID)、程序计数器、寄存器状态、内存分配情况、打开文件列表等。
  • 存储位置:每个进程的 PCB 存储在操作系统内核的进程表中,操作系统通过访问 PCB 来管理进程。

PID

  • 定义:PID是操作系统中用于标识和区分不同进程的唯一标识符。每个进程都有一个对应的 PID,用于在系统中唯一标识该进程。
  • 作用:PID用于操作系统识别和管理不同的进程,通过 PID 可以查找对应进程的 PCB,并对进程进行操作和控制。
  • 分配方式:PID 是由操作系统在创建进程时分配的,通常是一个唯一的整数值。
  • 使用方式:进程通过 PID 可以获取自身的信息,也可以通过 PID 与其他进程进行通信和协作。

PCB和PID

PCB是操作系统中用于管理进程信息的数据结构,包含了进程的所有关键信息。

PID是用于表示不同进程的唯一标识符,用于操作系统识别和管理进程。

getpid()

​ 头文件是unistd.h

#include <iostream>
#include <unistd.h>
int main() {
    pid_t pid = getpid();
    std::cout << "PID: " << pid << std::endl;
    return 0;
}

getppid()获取父进程pid

#include <iostream>
#include <unistd.h>

int main() {
    pid_t parent_pid = getppid();
    std::cout << "Parent PID: " << parent_pid << std::endl;
    return 0;
}

fork() 创建进程

需要头文件**unistd.h**

返回值为0表示子进程,返回值为子进程的pid表示父进程

fork中子进程被创建便开始共享代码,但是数据是分开的

#include <iostream>
#include <unistd.h>

int main() {
    pid_t pid = fork();

    if (pid == 0) {
        // 子进程代码
        std::cout << "This is the child process. PID: " << getpid() << std::endl;
    } else if (pid > 0) {
        // 父进程代码
        std::cout << "This is the parent process. Child PID: " << pid << std::endl;
    } else {
        // fork()失败
        std::cerr << "Fork failed." << std::endl;
        return 1;
    }

    return 0;
}

父子进程

父进程的代码和数据是从磁盘加载来的

子进程的代码和数据则是继承父进程的代码和数据而来

fork() 之后代码共享

为什么要创建子进程

让子进程执行和父进程不一样的代码。

实现并行处理、任务分割、资源隔离、错误处理、并发编程等功能,提高程序的性能、可靠性和灵活性。

/proc 目录内查看进程文件夹

每个运行中的进程在/proc目录下都有一个以进程pid命名的子目录,其中包含了该进程的相关信息,包括当前的工作路径。

怎样查看进程的当前工作路径?

  1. ps 进程名 获取进程pid
  2. 假设pid为1234 ls -l /proc/1234/cwd 查看路径

chdir()改变进程的工作目录

chdir(“路径”)

请确保指定的路径存在并且有相应的权限

进程状态

查看进程状态

ps ajx

ps ajx | head -1 查看一行

ps ajx | grep 'a' | grep -v 'b' 查看状态并且搜索a关键字,过滤b关键字

ps -la 用于显示当前用户的所有进程的详细信息,进程以列表形式显示

kill -l 列出linux系统可用的信号列表的命令


R运行状态

并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。

S睡眠状态

意味着进程在等待事件完成(可中断睡眠)

在此状态下,进程通常无法被Ctrl+C中断。因为S状态表示进程正在睡眠等待某些事情的发生,他可能是正在等待I/O操作完成、等待信号、等待资源等。此时,进程并不处于运行状态,因此无法响应Ctrl+C中断信号。

通常情况下,只有处于运行状态的进程才能接收并响应 Ctrl+C 信号。如果进程处于 “S” 状态,那么 Ctrl+C 信号可能会被系统忽略,直到进程重新进入运行状态或者其他条件发生变化。

但是可以使用 kill -9 pid 来强制终止,这个命令会发送一个SIGKILL信号给指定的进程,这个信号不可忽略,即使进程处于睡眠状态也会被强制终止。

D磁盘休眠状态

不可中断睡眠状态,在这个状态的进程通常会等待IO的结束。

t状态

  • “tracing stop” 是一种特定于调试器或跟踪工具的状态,用于暂停进程以进行调试和跟踪。

T停止状态

可以通过发送信号来停止进程。也可以通过发送信号让进程继续运行。

“stopped” 是一种通用状态,表示进程被暂停执行,可以由多种原因导致。

kill -19 pid暂停进程

kill -18 pid继续运行进程

X死亡状态

这个状态只是一个返回状态,你不会在任务列表里看到这个状态

Z僵尸状态

当子进程退出并且父进程没有读取到子进程退出的返回代码时就会产生僵尸进程

僵尸进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码

所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入僵尸状态

危害

进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),你交给我的任务,我办的怎么样了。可父进程如果一直不读取,那子进程就一直处于Z状态?

​ 是的!

维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说, Z状态一直不退出, PCB一直都要维护?

​ 是的!

那一个父进程创建了很多子进程,就是不回收,是不是就会造成内存资源的浪费?

​ 是的! 因为数据结构对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间!

内存泄漏?

​ 是的!

在这里插入图片描述

杀死僵尸进程

僵尸进程相当于进程已经死了,是不能被再次杀

孤儿进程

父进程提前退出,子进程称之为孤儿进程

孤儿进程被pid为1的init进程领养,所以变成僵尸进程后有init进程回收

杀死进程

kill -9 pid 强制杀死进程

kill -9 命令会发送一个 SIGKILL 信号给指定的进程,这个信号是不可忽略的,即使进程处于**“S"睡眠状态**也会被强制终止,即使目标进程处于 “D” 状态也可以终止。但它并不能解决造成进程进入 “D” 状态的根本”"问题,通常 “D” 状态表示系统中的某些 I/O 操作出现了问题。

Ctrl+C 终止在前台运行的进程

两种方式


并发和并行

  • 并发指多个任务可以重叠执行,但不一定同时执行。它利用了任务切换带来的时间重叠效应。

    多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发。

  • 并行指多个任务真正的同时(同一时刻)在多个处理元素上执行。

    多个进程在多个CPU下分别同时进行,这称之为并行。

阻塞态

进程由于等待某些事件的发生而暂时停止执行的状态。

在阻塞状态下,进程会暂停执行,不会占用 CPU 时间片,直到等待的事件发生或条件满足后才会被唤醒并继续执行。

阻塞和运行的状态变化,往往伴随着PCB被列入不同的队列中。 运行队列或资源的等待队列

挂起态

进程被暂时挂起,不会执行任何操作,但仍然保留在内存中。

挂起态进程通常保存在内存中,以确保快速恢复执行并保持进程的完整性。只有在系统需要释放内存或长时间不需要执行的情况下,才会将进程保存到磁盘中进行休眠或换出操作。 维护系统中的进程。

CPU内的寄存器

寄存器本身是硬件,具有数据的存储能力,CPU的寄存器硬件只有一套

CPU内部的数据可以有多套,有几个进程,就有几套和该进程对应的上下文数据

​ 寄存器!=寄存器的内容

CPU内部的所有的寄存器中的临时数据,叫做进程的上下文

入不同的队列中。 运行队列或资源的等待队列

挂起态

进程被暂时挂起,不会执行任何操作,但仍然保留在内存中。

挂起态进程通常保存在内存中,以确保快速恢复执行并保持进程的完整性。只有在系统需要释放内存或长时间不需要执行的情况下,才会将进程保存到磁盘中进行休眠或换出操作。 维护系统中的进程。

CPU内的寄存器

寄存器本身是硬件,具有数据的存储能力,CPU的寄存器硬件只有一套

CPU内部的数据可以有多套,有几个进程,就有几套和该进程对应的上下文数据

​ 寄存器!=寄存器的内容

CPU内部的所有的寄存器中的临时数据,叫做进程的上下文


网站公告

今日签到

点亮在社区的每一天
去签到