进程概念 | 进程状态 | 进程优先级

news2025/2/4 6:36:36

进程的基本概念

  • 课本概念:程序的一个执行实例,正在执行的程序等。
  • 核心观点:担当分配系统资源(cpu时间、内存)的实体。

资源占用

它占用系统资源向CPU时间,内存等不同进程的资源是相互隔离的,确保进程的稳定运行。

结构组成

包含代码段存放程序代码,数据段存放全局变量的堆栈段,用于函数调用,系局部变量存储等部分。

父子关系

进程之间存在父子关系,父进程可以创建子进程,子进程可以继承父进程的某些属性,如文件描述符等。

  • 在Linux中,进程是程序执行时的一个实例。
  • 操作系统本质是一种进行软硬件资源管理的软件。
  • 操作系统对上以人为本。
  • 操作系统目的要对上给用户提供一个稳定的,高效的,安全的运行环境。
  • 而采用对下进行软硬件资源管理的手段来保证资源是稳定的,高效的,安全的,能进行良好的工作。

操作系统进行内存管理、文件管理、进程管理和驱动管理。

而对于进程管理,在进程运行的过程中,从进程加载,进程运行到进程结束的整个生命周期里,操作系统要对进程进行管理。

那么操作系统如何对进程进行管理?

先描述再组织。

也就是说操作系统为了管理进程,给进程创建了一个数据结构,用来管理每一个不同进程。其中这个数据结构中包含各种该进程的属性。便于操作系统进行管理不同的进程。

进程 = 内核数据结构struct(自己对应的页表和虚拟地址空间之间的映射)+ 程序的代码和数据

描述进程PCB

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

  • Task_struct是PCB的其中一种。
  • 在Linux中描述进程的结构体叫做task_struct。
  • taskStruct是Linux内核数据内核的一种数据结构,它会被加载到RAM。内存里并且包含进程的信息。
  • Task struct是纯内存及数据结构,关机之后启动的内容和上一次不同,不是磁盘级别的不会被永久保存下来。

task_struct内容

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

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

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
    printf("pid: %d\n", getpid());
    printf("ppid: %d\n", getppid());
    return 0;
}
  • 进程ID:pid
  • 父进程ID:ppid

查看进程,创建子进程

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
    int ret = fork();
    printf("hello proc : %d!, ret: %d\n", getpid(), ret);
    sleep(1);
    return 0;
}

在fork函数之后,两个进程是父子关系,一般而言,代码共享,但是数据是各自私有一份的,采用写时拷贝。

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
    int ret = fork();
    if(ret < 0)
    {
        perror("fork");
        return 1;
    }
   
    else if(ret == 0)
    { 
        //child
        printf("I am child : %d!, ret: %d\n", getpid(), ret);
    }
    
    else
    { 
        //father
        printf("I am father : %d!, ret: %d\n", getpid(), ret);
    }
    sleep(1);
    return 0;
}

创建多进程multprocess

#include <stdio.h>
#include <iostream>
#include <unistd.h>
using namespace std;
#include <vector>

//创建十个子进程
int countNum = 10;

void SubProcess()
{
    while(true)
    {
        cout << "I am child process , pid : " << getpid() << " , "  << getppid() << endl;
        sleep(5);
    }
}

int main()
{
    vector<pid_t> allchild;
    for(int i = 0 ; i < countNum ; i++)
    {
        pid_t id = fork();//创建子进程
        if(id == 0)
        {
            //子进程
            SubProcess();
        }
        //父进程
       // else if(id > 0)
        //{
            allchild.push_back(id);
        //}
       // else{
       //     perror("fork");
       //     return 1;
       // }
    }

    cout << "我所有的孩子是:";
    for(pid_t e : allchild)
    {
        cout << e << " ";
    }
    cout << endl;
    sleep(10);
    while(true)
    {
        cout << "I am father process , pid : " << getpid() << " , "  << getppid() << endl;
        sleep(10);
    }

    return 0;
}

一个函数fork怎么会有两个返回值?

  • Fork函数是一个系统调用的函数,是操作系统用来创建子进程的一个函数。
  • 在创建子进程之后,fork函数之后父子进程的核心工作都做完了,并且父子进程都已经运行了。
  • Folk一定有很多执行fork函数return的时候,前面的核心工作代码已经执行完了。
  • 也就是说当前子进程已经被创建了。
  • 子进程被创建的时候,他的代码,数据结构以及taskstruct都源自于父进程的代码和数据以及父进程的task struct。父子的数据独立。
  • 所以父子进程函数fork之后的返回值不同。
  • 对于父进程fork函数返回新创建子进程的标识符pid,这个pid是一个大于0的值,附近层可以通过这个pid来对此进程进行管理,如监视子进程的状态,向子进程发出信号等。
  • 对于子进程fork函数返回零是为了让子进程能够区别自己是子进程的身份,因为子进程可以通过这个返回值知道自己是新创建的子进程从而执行相应的代码逻辑比如执行与父进程不同的任务。

进程状态

看看Linux内核源代码怎么说?

为了弄明白正在运行的进程是什么意思,我们需要知道进程的不同状态,一个进程可以有几个状态在Linux内核里。进程有时候也叫做任务。下面的状态在kernel源代码里面定义。

/*
* 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运行状态

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

S休眠状态

意味着进程在等待事件完成,这里的睡眠有时候也可以被叫做可中断睡眠。

D磁盘休眠状态Disk sleep

有时候也叫不可中断睡眠状态,在这个状态的进程通常会等待io的结束。

T的状态Stopped

通过发送Sigstop信号来给进程来停止进程。这个可以被暂停的进程,可以通过发送sig cont信号让进程继续运行。

死亡状态dead

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

特殊的进程状态

僵尸进程

僵尸进程的概念。
  • 僵尸进程是一个比较特殊的状态。当子进程退出并且副进程没有读取到子进程退出的返回代码时,子进程就属于僵尸进程。
  • 僵尸进程会议终止状态保持在进程表中,并且会一直等待父进程读取退出状态代码。
  • 所以只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态。
僵尸进程的代码实例
#include <stdio.h>
#include <stdlib.h>

int main()
{
    pid_t id = fork();
    if(id < 0)
    {
        perror("fork");
        return 1;
    }
    else if(id > 0)
    { 
        //parent
        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一直都要被维护。
  • 那一个父进程创建了很多子进程,就是不回收就会造成内存资源的浪费,因为数据结构对象本身就是要占用内存。会在内存中进行开辟空间抑制持续占用资源,最终导致内存泄露

孤儿进程

孤儿进程的概念
  • 父进程先退出,子进程则就称为孤儿进程。孤儿进程被1号进程领养,被1号进程回收♻️。
孤儿进程的代码实例
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
    pid_t id = fork();
    if(id < 0)
    {
        perror("fork");
        return 1;
    }

    else if(id == 0)
    {
        //child
        printf("I am child, pid : %d\n", getpid());
    sleep(10);
    }

    else
    {    
        //parent
    printf("I am parent, pid: %d\n", getpid());
    sleep(3);
    exit(0);
    }
    return 0;
}

进程优先级

优先级概念

  • CPU资源分配的先后顺序就是指进程的优先权。因为CPU的资源是有限的,在一个电脑🖥️里面可能只有一个或者多个CPU,但是进程有很多个。
  • Linux操作系统,Windows操作系统的大部分民用级别的操作系统都是采用分时操作系统。分时操作系统保证调度任务绝对公平。
  • 优先权高的进程有优先执行权力。配置进程优先权对于多任务环境的Linux很有用,可以改善系统性能。
  • 还可以把进程运行到指定的CPU上,这样一来把不重要的进程安排到某个CPU可以大大改善系统整体性能。

查看优先级

  • uid代表执行者的身份。
  • pid代表这个进程的代号
  • ppid表示这个进程是由哪一个进程发展延伸而来的,以及父进程的代号。
  • pri代表这个进程可被执行的优先级,其数越小越早被执行。
  • ni代表这个进程的nice值。

Pri && ni

新的pri = 旧的pri + nice值

  • 当nice值为负值的时候,那么该程序将会优先级值将变小及其优先级会变高,则其越快被执行。
  • 调整进程优先级,在Linux下就是调整进程的nice值。
  • Nice的值取值范围是-20~19,一共是40个级别。

Pri vs ni

  • 进程的nice值不是进程的优先级,进程的nice值会影响到进程优先级变化。
  • Nice值是进程优先级的修正数据。

用top命令更改已经存在进程的nice值

进入top后按r👉🏻输入进程pid👉🏻输入nice值

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2191202.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux中swap分区

swap 分区的创建方法演示&#xff1a; 方法1&#xff1a;fdisk &#xff08;首先查看 fdisk /dev/sda 中 swapID。由于 Linux 的 fdisk 默认会将分区的 ID 设置为 Linux 的文件系统&#xff0c;所以需要设置一下 systemID&#xff09; 解决方法 重启或者执行命令 第二个交换分…

主机可以ping通linux虚拟机但linux虚拟机无法ping通主机的解决办法

出现这个问题一般是由于物理主机的防火墙挡住了ping包&#xff0c;可以试试看把主机的防火墙关闭看看 如果可以ping通的话那么试试看添加规则将虚拟机ip添加进去 高级设置&#xff0c;入站规则&#xff0c;新建规则 下列ip地址添加虚拟机的ip地址&#xff08;使用桥接网络&…

修改Anaconda虚拟环境默认安装路径(Linux系统)

文章目录 修改Anaconda虚拟环境默认安装路径(Linux系统)1.方法一&#xff1a;使用--prefix参数2.方法二&#xff1a;配置conda环境的默认安装位置 修改Anaconda虚拟环境默认安装路径(Linux系统) 1.方法一&#xff1a;使用--prefix参数 在创建虚拟环境时&#xff0c;使用--pre…

Vue3 中Ref的最佳实践

在vue3中如果我们需要获取一个响应式的变量&#xff0c;可以使用ref来定义一个变量。 const name ref( "" );name.value "test" 定义好后&#xff0c;就可以实现修改状态&#xff0c;更新UI的效果了。 在这个基础上&#xff0c;本文主要讨论跨组件时如何…

基于STM32的智能风扇控制系统设计

引言 本项目将基于STM32微控制器设计一个智能风扇控制系统&#xff0c;通过温度传感器实时检测环境温度&#xff0c;并根据预设的温度范围自动调节风扇的转速。该系统展示了STM32的PWM输出、传感器接口以及自动控制应用的实现。 环境准备 1. 硬件设备 STM32F103C8T6 开发板…

Python 语言学习——应用1.1 数字图像处理(第一节,颜色)

目录 1.基础知识 2.实战演示 1.基础知识&#xff1a; 1.图像的表示. 函数表示&#xff1a;图像是二维信号&#xff0c;定义为二维函数f(x,y)&#xff0c;其中&#xff0c;x、y是空间坐标&#xff0c;f(x,y)是点(x,y)的幅值。拓展看&#xff0c;视频&#xff0c;又称动态图像…

SOMEIP_ETS_166: SD_TestFieldUINT8

测试目的&#xff1a; 验证DUT能够通过Getter和Setter方法正确地发送和接收TestFieldUINT8字段的值。 描述 本测试用例旨在确保DUT的ETS能够响应Tester的请求&#xff0c;正确地使用Getter方法获取TestFieldUINT8的值&#xff0c;以及使用Setter方法设置新的值。 测试拓扑&…

QGIS中怎么加载数据(如矢量shp与栅格数据)

最近有不少初学者来问我qgis里怎么加载数据 这个与arcgis中的操作其实也是类似的&#xff0c;也是通过软件的里面&#xff0b;号就行了 下面是我对这个问题的解决思路&#xff1a; 一种是直接把图层文件拖进去&#xff0c;但是这种方法很有局限性&#xff0c;下面我还说明一…

JavaWeb的小结02

第2章-第2节 一、知识点 HttpServletRequest请求对象、HttpServletResponse响应对象、响应内容类型Content-Type、请求转发、重定向、ServletContext对象。 二、目标 深刻理解HttpServletRequest对象的作用。 深刻理解HttpServletResponse对象的作用。 掌握HttpServletRequ…

什么是请求转发?

请求转发 解释 请求转发,将前端发送的请求转发到别的资源 别的资源是指: servlet,页面 即: 请求转发,可以将请求转发值另外一个servlet;也可以是将请求转发至页面 1、 请求转发演示 1.1 请求转发跳转页面 实战: 之前注册练习,修改: 实现注册完跳转到登录页面 1.2 请求转发…

【Matlab案例】imageJ + matlab 实现物体轨迹追踪及路径彩色上色

我们经常看到一些文献中对细胞或者粒子的运动轨迹进行上色&#xff0c;不同的颜色对应着不同的时间。一纯色的轨迹实现起来很方便&#xff0c;彩色的轨迹如何实现呢&#xff1f;本文使用imageJ获取轨迹数据&#xff0c;使用matlab对轨迹进行上色。结果如下&#xff1a; 1. im…

Java | Leetcode Java题解之第457题环形数组是否存在循环

题目&#xff1a; 题解&#xff1a; class Solution {public boolean circularArrayLoop(int[] nums) {int n nums.length;for (int i 0; i < n; i) {if (nums[i] 0) {continue;}int slow i, fast next(nums, i);// 判断非零且方向相同while (nums[slow] * nums[fast]…

Python爬虫(二)--http基本原理(Python Crawler (2) Basic Principles of HTTP)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

TriLite完成A轮扩展融资:加速AR微型投影仪技术创新与市场拓展

近日,全球领先的AR微型投影仪开发商TriLite宣布成功完成A轮扩展融资,将A轮融资总额提升至超过2000万欧元。这一轮融资不仅彰显了资本市场对TriLite技术实力和市场潜力的高度认可,更为其后续在AR微型投影仪领域的技术研发、产品迭代以及市场拓展提供了坚实的资金保障。以下是…

力扣刷题 | 两数之和

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 给定一个整数数组 nums 和…

C++ | Leetcode C++题解之第456题132模式

题目&#xff1a; 题解&#xff1a; class Solution { public:bool find132pattern(vector<int>& nums) {int n nums.size();vector<int> candidate_i {nums[0]};vector<int> candidate_j {nums[0]};for (int k 1; k < n; k) {auto it_i upper_…

Leetcode—416. 分割等和子集【中等】

2024每日刷题&#xff08;172&#xff09; Leetcode—416. 分割等和子集 C实现代码 class Solution { public:bool canPartition(vector<int>& nums) {int sum accumulate(nums.begin(), nums.end(), 0);if(sum % 2) {return false;}int m nums.size();int subSu…

自动售卖柜目标检测数据集 4880张 商品数据集 voc yolo

自动售货机商品检测数据集 名称 自动售货机商品检测数据集 (Automatic Vending Machine Product Detection Dataset) 规模 图像数量&#xff1a;4880张图像。类别&#xff1a;30种不同的商品类别。 数据划分 训练集 (Train)&#xff1a;通常占总数据的80%左右&#xff0c;…

【AI知识点】二项分布(Binomial Distribution)

二项分布&#xff08;Binomial Distribution&#xff09; 是概率论和统计学中描述独立重复的伯努利试验中成功次数的离散概率分布。它是基于多次独立的伯努利试验的扩展&#xff0c;用于描述在 n n n 次试验中发生成功的次数。 1. 二项分布的定义 二项分布用于描述在 n n n…

利用GPU进行训练

文章目录 一、GPU训练模型二、对比使用gpu和cpu进行训练所花费的时间三、GPU训练模型的第二种表达方式 一、GPU训练模型 GPU只能够训练三种变量&#xff0c;分别是&#xff1a; 网络模型 数据&#xff08;输入&#xff0c;标注targets&#xff09; 损失函数 使用方式是.cuda…