谈一谈Linux下的进程和线程

文章目录

  • 进程
  • 线程
  • 进程与线程比较

进程

什么是进程?
概念上来说,进程是担当OS资源分配的实体。通俗来说,进程是我们OS上一个在运行的程序。
我们的OS上不止有一个进程,当我们的某一个进程像是去磁盘上读文件时,由于磁盘的速度很慢,这是为了提高CPU的利用率,这时就会将该进程挂起,而去执行另一个进程,直到磁盘读写完毕,给OS一个信号,OS从而在去调度原来被挂起的进程。
进程不止有一个,所以就需要我们对进程进行管理,怎么管理:先描述,后组织,将进程的属性抽象成结构体,然后将每个进程的结构体通过链表组织起来。其中所谓 的结构体就是我们的PCB—进程控制模块,在Linux中就是我们的task_struct。每一个进程都有其独立的PCB,那么操作系统对进程的管理就变为了实际上对PCB进行管理。PCB放在哪个组织结构里实则对应着的是其不同的进程状态,我们的进程至少具备三种基本状态:运行状态,就绪状态,阻塞状态。其分别对应着运行队列,就绪队列,阻塞队列这样的组织结构。
运行状态:正在运行的进程
就绪状态:随时可以运行,但CPU正在被其他进程所占有
阻塞状态:由于等待输入输出等时间,无法运行,及时给它CUP控制权,也无法运行。
若有大量的阻塞状态,回导致我们的内存利用率不高,所以通常会把阻塞状态的进程的物理内存换入到磁盘中,只留有其内核数据在内存中,当需要再运行的时候,再从磁盘中写回,我们将这种状态成为挂起状态。
task_struct中有什么?

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

那我们的进程都要是处于就绪状态,OS该如何决策调度哪一个进程呢?这就是是OS调度器要干的事情啦?我们可以在可以简单的说名以下:每个进程都有优先级,优先级越高,则越是容易被调度,当然这个优先级的计算,是调度器帮我们去评判的,那么我们人为的可以干预吗,是可以的!我们的nice值就可以帮助我们进行优先级的干预。

PRI是进程的优先级,其表示该进程被cpu执行的先后顺序,其值越小,优先级越高。 那么NI是啥呢?可以将其理解为优先级的修正数值。
因此调整nice值就是调整进程的优先级。nice值的取值范围是-19 - 20。

那么如何更改nice值

可以使用top命令进行修改。其使用格式如下: 进入top后按“r”–>输入进程PID–>输入nice值。

调整已存在进程的nice:renice

我们的每个进程都拥有其独立的进程地址空间,以及页表。这样的设计使得我们多进程得以实现,避免了直接对物理内存操作而引起地址冲突,再者,由于虚拟地址到物理地址之间要经过映射,并且我们对进程地址空间进行了分段,因此在映射时,我们自然就可以进行一些检查,检查其访问的地址是否安全,以及该地址所存储数据的属性是否允许我们进行操作等;进程地址空间使得让每一个进程都觉得自己拥有整个内存,它不关心其他的进程,这也是进程独立的体现,并且,由于有局部性原理,我们可以将一些暂时不用的其他进程所占用的内存,换出到磁盘中,从而给当前进程用,提高了内存的使用效率。
我们可以在当前进程中,利用fork函数创建子进程,我们的进程具有独立性,创建的子进程通过拷贝父进程的PCB,再更具自己的情况,稍加更改,就成了自己的PCB结构体,因此在父进程在创建子进程前的一些属性和数据,例如文件描述符表等子进程都是可以看见的。当然子进程也会创建出自己的进程地址空间。只不过为了提高效率,节约内存其采用读时共享,写时拷贝的策略,在读时,和父进程映射同一块物理内存,只有写时,才会重新将数据映射到心的物理内存上。
新创建出来的子进程,若我们不进行等待,就会形成僵尸进程,僵尸进程会占用一定的资源,我们的子进程在退出时,其会保留一些退出信息,当然由于进程并未完全退出,所以其PCB当然也存在在内核中,所以为了减少资源的浪费,我们要对子进程进行回收,回收可以采用父进程阻塞式的等待,父进程进行轮询判断等方式进行回收,还可以通过信号的方式:因为我们的子进程在退出时,会像父进程发送SIGCHILD信号,所以我们若不关心退出信息,可以通过显式的忽略该信号(特例),关心的话可以在自定义信号处理函数中进行等待(循还+非阻塞式等待)。
我们在的进程还可以进行替换,利用execv函数族进行进程替换,其本质就是将该进程的代码和数据进行替换,PCB等结构不变。
进程终止我们可以通过exit函数,信号,直接return等方式进行退出。

线程

什么叫线程?
线程是OS进行调度运行的最小单位,线程运行在进程的内部,是进程实际运行的单位。进程是承担OS资源的实体,那么线程就是承担进程部分资源的一个实体。
在一个进程内部,不止有一个进程,那么我们是不是要对其进行管理,先描述,后组织,将其属性抽象从某种结构体,我们将这种结构体成为TCB。也就是说,OS实际调度的是一个个TCB,当然这是对于一般OS来说。Linux有自己的方案。
Linux认为既然线程的结构和进程类似,那么我就不用去再实现线程的一套结构,而是将一个线程当作一个特殊的进程来看待,这样的优势则是,减少了我们结构的复杂度,从而降低了BUG的产生。
因此,现在对于CPU而言,其不管你是线程还是进程,它所认的就是PCB结构体。
为了能够实现线程,我们就要将原来进程的那一套进行一些更改。这就涉及到了线程的一些特性。我们的同一个进程的多个线程之间是能够共享代码段,数据段,打开的文件等资源的,也就是说其要共享进程地址空间上的一些数据。这当然好办,我们在创建这个特殊的进程时,将其和创建它的进程的地址空间进行共享。
当然除了共享的数据以外,每个线程都是一个执行流,它也应该拥有自己的私有栈,独立的上下文数据,信号屏蔽字,线程ID,调度优先级等。后面的一些数据,由于线程有独立的PCB,因此可以私有化,但是,栈怎么办?用户栈只有一个,要是都放在用户栈里,岂不是太过于混乱。Linux的解决办法是这样的:此时,我们的线程对于上层用户来说,操作是有难度的,所以有第三方库经过对Linux 的线程接口封装为我们提供了使用Linux线程更方便的方法,在使用线程时,程序运行起来后,会将第三方库加载到我们的mmp共享区域,这个库不光为我们解决了使用线程系统调用接口难的问题,还帮我们提供了线程所使用的栈。这个栈在哪呢?就在我们的mmp中,并且我们的线程id就是其栈的起始地址,而我们ps -aL中显式的LWP则是内核中标记线程的id。它与我们用户所看到的线程id是一一对应的。
所以Linux下的进程<=其他OS下的进程。OS下的进程我们称为轻量级进程。

进程与线程比较

进程承担OS资源分配的实体,而线程是CPU的基本调度单位,线程在进程中。
线程之间大多数资源是共享的,所以线程间通信方便,而进程是独立的,所以进程间通信难度较大。
线程能够减少并发执行的时间和空间开销-----体现在:
线程的创建更加简单。
线程进行切换时效率更快。因为我们在进行切换时,不仅仅是将PCB换下去,保存上下文,我们的计算机为了更快的效率,在CPU和内存之间还由多级缓存,我们的线程中的资源好多都是共享的,所以缓存命中率高,而进程切换,则需要重新加载缓存。
线程的释放也要比进程快。
但是我们同一进程内的线程异常退出,那么我们整个进程也都退出了,而且线程由于一些数据共享的问题,会带来线程安全。

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

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

相关文章

学习pytorch18 pytorch完整的模型训练流程

pytorch完整的模型训练流程 1. 流程1. 整理训练数据 使用CIFAR10数据集2. 搭建网络结构3. 构建损失函数4. 使用优化器5. 训练模型6. 测试数据 计算模型预测正确率7. 保存模型 2. 代码1. model.py2. train.py 3. 结果tensorboard结果以下图片 颜色较浅的线是真实计算的值&#x…

国产化软件突围!怿星科技eStation产品荣获2023铃轩奖“前瞻优秀奖”

11月11日&#xff0c;2023中国汽车供应链峰会暨第八届铃轩奖颁奖典礼在江苏省昆山市举行。怿星科技凭借eStation产品&#xff0c;荣获2023铃轩奖“前瞻智能座舱类优秀奖”&#xff0c;怿星CEO潘凯受邀出席铃轩奖晚会并代表领奖。 2023铃轩奖“前瞻智能座舱类优秀奖” 铃轩奖&a…

el-table 跨页多选

步骤一 在<el-table>中:row-key"getRowKeys"和selection-change"handleSelectionChange" 在<el-table-column>中type"selection"那列&#xff0c;添加:reserve-selection"true" <el-table:data"tableData"r…

队列排序:给定序列a,每次操作将a[1]移动到 从右往左第一个严格小于a[1]的元素的下一个位置,求能否使序列有序,若可以,求最少操作次数

题目 思路&#xff1a; 赛时代码&#xff08;先求右起最长有序区间长度&#xff0c;再求左边最小值是否小于等于右边有序区间左端点的数&#xff09; #include<bits/stdc.h> using namespace std; #define int long long const int maxn 1e6 5; int a[maxn]; int n; …

阿里云磁盘在线扩容

我们从阿里云的控制面板中给硬盘扩容后结果发现我们的磁盘空间并没有改变 注意&#xff1a;本次操作是针对CentOS 7的 &#xfeff;#使用df -h并没有发现我们的磁盘空间增加 #使用fdisk -l发现确实还有部分空间 运行df -h命令查看云盘分区大小。 以下示例返回分区&#xf…

python3安装redis

#!/usr/bin/python3import os import platform import argparse import shutil# 自定义变量 default_system "ubuntu" default_redis_version "6.2.6" default_install_path "/usr/local/redis" default_local_package_dir os.path.dirname(…

eve-ng镜像模拟设备-信息安全管理与评估-2023国赛

eve-ng镜像模拟设备-信息安全管理与评估-2023国赛 author&#xff1a;leadlife data&#xff1a;2023/12/4 mains&#xff1a;EVE-ng 模拟器 - 信息安全管理与评估模拟环境部署 references&#xff1a; EVE-ng 官网&#xff1a;https://www.eve-ng.net/EVE-ng 中文网&#xff1…

嵌入版python作为便携计算器(安装及配置ipython)

今天用别的电脑调试C&#xff0c;需要计算反三角函数时发现没有趁手工具&#xff0c;忽然想用python作为便携计算器放在U盘&#xff0c;遂想到嵌入版python 懒得自己配可以直接下载&#xff0c;使用方法见第4节 1&#xff0c;下载embeddable python&#xff08;嵌入版python&…

React中传入props.children后, 为什么会导致组件的重新渲染?

传入props.children后, 为什么会导致组件的重新渲染&#xff1f; 问题描述 在 react 中, 我想要对组件的渲染进行优化, 遇到了一个非常意思的问题, 当我向一个组件中传入了 props.children 之后, 每次父组件重新渲染都会导致这个组件的重新渲染; 它看起来的表现就像是被memo包…

【1day】​万户协同办公平台 convertFile 任意文件读取漏洞学习

注:该文章来自作者日常学习笔记,请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与作者无关。 目录 一、漏洞描述 二、影响版本 三、资产测绘 四、漏洞复现

图的邻接链表储存

喷了一节课 。。。。。。。、。 #include<stdio.h> #include<stdlib.h> #define MAXNUM 20 //每一个顶点的节点结构&#xff08;单链表&#xff09; typedef struct ANode{ int adjvex;//顶点指向的位置 struct ArcNode *next;//指向下一个顶点 …

C++ 内存分区模型

目录 程序运行前 代码区 全局区 程序运行后 new 在堆区开辟数据 delete释放堆区数据 堆区开辟数组 内存分区模型 栈&#xff08;Stack&#xff09; 堆&#xff08;Heap&#xff09; 全局/静态存储区&#xff08;Global/Static Storage&#xff09; 常量存储区&am…

力扣230. 二叉搜索树中第K小的元素

深度优先搜索 思路&#xff1a; 二叉搜索树的特性&#xff0c;通过中序遍历得到有序序列&#xff0c;则遍历到第K个节点的时候即为结果&#xff1b;使用栈通过深度优先遍历进行中序遍历&#xff1a; 先将节点和左子节点压栈&#xff1b;然后栈顶上就是“最左”叶子节点&#x…

Linux DAC权限的简单应用

Linux的DAC&#xff08;Discretionary Access Control&#xff09;权限模型是一种常见的访问控制机制&#xff0c;它用于管理文件和目录的访问权限。作为一名经验丰富的Linux系统安全工程师&#xff0c;我会尽可能以简单明了的方式向计算机小白介绍Linux DAC权限模型。 在Linu…

jenkins中“Jenkins Plot Plugin”的使用方法,比较两个excel的数据差异

Jenkins Plot Plugin是Jenkins的一个插件&#xff0c;它可以用于生成图表和报表&#xff0c;以便更好地理解和分析构建和测试数据。下面是使用Jenkins Plot Plugin比较两个Excel数据差异的步骤&#xff1a; 1.安装Jenkins Plot Plugin&#xff1a;在Jenkins的插件管理页面搜索…

使用 Axios 进行网络请求的全面指南

使用 Axios 进行网络请求的全面指南 本文将向您介绍如何使用 Axios 进行网络请求。通过分步指南和示例代码&#xff0c;您将学习如何使用 Axios 库在前端应用程序中发送 GET、POST、PUT 和 DELETE 请求&#xff0c;并处理响应数据和错误。 准备工作 在开始之前&#xff0c;请…

电子学会C/C++编程等级考试2021年09月(五级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:抓牛 农夫知道一头牛的位置,想要抓住它。农夫和牛都位于数轴上,农夫起始位于点N(0<=N<=100000),牛位于点K(0<=K<=100000)。农夫有两种移动方式: 1、从X移动到X-1或X+1,每次移动花费一分钟 2、从X移动到2*X,每…

ubuntu18.04安装opencv-4.5.5+opencv_contrib-4.5.5

一、安装opencv依赖 sudo apt-get install build-essential sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-d…

Navicat 技术指引 | 适用于 GaussDB 分布式的自动运行功能

Navicat Premium&#xff08;16.3.3 Windows 版或以上&#xff09;正式支持 GaussDB 分布式数据库。GaussDB 分布式模式更适合对系统可用性和数据处理能力要求较高的场景。Navicat 工具不仅提供可视化数据查看和编辑功能&#xff0c;还提供强大的高阶功能&#xff08;如模型、结…

「Python编程基础」第7章:字符串操作

文章目录 一、回顾二、新手容易踩坑的引号三、转义字符四、多行字符串写法五、注释六、字符串索引和切片七、字符串的in 和 not in八、字符串拼接九、转换大小写十、合并字符串join()十一、分割字符串split()十二、字符串替换 replace()十三、字符串内容判断方法十四、字符串内…