当前位置: 首页 > news >正文

【Linux】进程理解与学习Ⅰ-进程概念

环境:centos7.6,腾讯云服务器
Linux文章都放在了专栏:【Linux】欢迎支持订阅🌹
相关文章推荐:
【Linux】冯.诺依曼体系结构与操作系统

进程概念

什么是进程?

进程是什么?我们打开任务管理器可以看到有很多的程序正在运行状态,并且上面写着进程二字。难道进程就是指这些被运行起来的程序吗?课本上对于进程是这么说的:程序的一个执行实例,正在执行的程序等

windows下的进程

但是实际上这种说法并不完全准确?(举个例子,一个仅仅进入学校的人,并不能算是这个学校的学生,只有这个人的信息被加载到学校的教务系统,并且被这个学校所管理的人,才称得上学生。这里的学校就是指内存,数据只有加载到内存,并被OS所管理,这才算是一个完整的进程)。

os管理进程

在前文我们知道了cpu一般不会与外设进行直接沟通,而是与内存打交道。所以我们在磁盘上的程序被运行时要将数据与代码加载到内存中。由操作系统来进行管理。具体怎么来管理呢?先描述,再组织。

所谓的先描述实际上是指OS会用一个特定的结构体PCB/task_struct)来提取该进程的各种属性(这里的属性与加载到内存中的数据与代码无关,或者说仅仅只有一点点的关系,即可以通过对应的 task_struct找到该进程的代码和数据)。组织是指OS会以链表或者其它的数据结构将各个task_struct组织起来,方便管理。(对进程的修改--->对链表或者其它数据结构的增删查改,比如我们结束一个进程,实际上就是删掉数据结构中对应的pcb

★上面啰嗦一大堆,无非就是说两个事:

  • 结论一进程=os内核关于该进程的相关数据结构(PCB/task_struct)+当前程序加载到内存的代码与数据

  • 结论二OS如何管理进程?先描述(pcb/task_struct),再组织(链表等数据结构)。

PCB — 进程控制块

进程需要被OS管理,管理的本质就是先描述,再组织。而PCB就是用来描述进程的一种特定结构体。在Linux系统下的PCB就是task_struct

task_struct内容分类

task_struct结构体中主要包含了以下信息,了解一下即可:

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

如何查看进程

第一种方法:通过ps指令

我们输入ps axj就可以查看当前所有进程信息,同时,由于进程信息较多,我们可以利用之前学过的管道,以及grep用来筛选过滤,从而拿到我们想要的进程信息。(ps -l可以查看当前bash下的进程信息)如下:

第二种方法:通过函数getpid()

在上面task_struct内容中,有一个是标识符,用来区分其他进程。这里的标识符,实际就是指PID每一个进程都有自己的pid,并且每一次运行,pid的值都会发生变化(一般都是逐渐递增,当下一次重新登陆时,又是随机值)。

而我们可以通过系统调用函数getpid()来获取当前进程的pid。我们可以用man手册来查询getpid()的使用。我们可以通过如下的简单代码来验证。

#include<stdio.h>
//头文件包含
#include<unistd.h>
#include<sys/types.h>
int main()
{while(1){//获取当前进程pidprintf("hello world,我的pid:%d\n",getpid());                                             sleep(1);                                                                     }                                                                               return 0;                                                                       } 
第三种方法:在路径/proc下查看

事实上,我们在执行一个程序时,会在/proc目录下生成一个以当前程序的pid命名的目录文件,该目录文件内包含了当前进程的所有信息。并且还有一个特点:当该程序停止运行时,以pid命名的文件会自动销毁

如何中止进程

★三种方法:

  • 我们可以通过指令kill -9进程pid来中止进程

  • 通过热键ctrl c来中止当前进程

  • 通过指令killall 进程名称 来中止进程

三种方式终止进程

父子进程

PPID

进程之间存在父子关系,我们知道,bash是命令行解释器,当我们在命令行输入指令执行一个进程时,我们执行的进程就是bash的子进程。究竟是否如我们所说?我们可以验证一下,当然,在此之前我们要先谈一下PPID,PPID就是当前进程的父进程的pid

fork创建子进程

我们也可以通过系统调用函数fork用来给当前进程创建子进程。我们用man手册查询fork的用法。

我们可以通过如下代码来进行简单测试:

#include<stdio.h>
#include<assert.h>
#include<unistd.h> 
int main()
{//我们用ret来接受fork的返回值pid_t ret=fork();assert(ret!=-1);//断言一下//我们通常使用if语句,用来进行执行流分流if(ret == 0)                            {           while(1){       //此时是子进程,fork给子进程返回0printf("我是子进程,pid:%d,ppid:%d,ret:%d,&ret:%p\n",getpid(),getppid(),ret,&ret);        sleep(1);                                                                         }          }  else if(ret >0){              while(1){       //此时是父进程,fork给父进程返回子进程的pidprintf("我是父进程,pid:%d,ppid:%d,ret:%d,&ret:%p\n",getpid(),getppid(),ret,&ret);sleep(1);                                                                         }          }return 0;}

运行结果

我们发现,确实如此,不过这里有一个疑问,为什么ret的地址相同,但是ret的值却不相同呢?我们从未见过这种现象:同一个变量竟然有两个返回值。这是为什么呢?实际上,我们在函数的最后有一个return 0,而fork之后的代码是父子进程共享的,也就是说,return这个语句被执行了两次,并且当return执行时,函数体内部是已经执行完了的。所以会有两个返回值。

为了验证fork之后的代码,被父子进程共享,我们可以写一个简简单单的代码用来测试一下:

#include<stdio.h>
#include<unistd.h>int main(){int ret = fork();//这里只有一个printfprintf("hello proc,pid:%d,ppid:%d,ret:%d\n", getpid(),getppid(),ret);                          sleep(1);return 0;}

运行结果

我们发现,确实如此。不仅如此,进程还具有独立性,我们可以定义一个全局变量,父进程对

全局变量进行修改,我们发现不会影响到子进程中的那个全局变量。我们也可以进行验证:

#include<stdio.h>
#include<unistd.h>
//定义全局变量
int a=100;
int main(){pid_t ret=fork();if(ret == 0){while(1){//子进程,不对a做修改printf("我是子进程,a=%d,&a=:%p\n",a,&a);sleep(1);}}else {while(1){//父进程,对全局变量a进行修改                                                            a+=100;//假如进程不具有独立性,那么父进程的修改也会影响子进程,究竟会不会呢?printf("我是父进程,a=%d,&a=:%p\n",a,&a);sleep(1);}}return 0;}

结果

我们发现确实如此,不过为什么同一个地址,对内容进行修改却不会互相影响呢?实际上这里的地址并不是真正的物理地址,并且当进程尝试对数据进行修改时,还会触发写时拷贝。(具体放在后面进程地址空间章节详细讲解)。

总结

★上面写了这么多,总结如下:

  • 命令行启动的程序,都会变成bash的子进程

  • 我们可以通过fork为当前进程创建子进程,fork的返回值给子进程返回0,给父进程返回子进程的pid,创建进程失败时返回-1

  • fork之后的代码被父子进程共享(但是谁先运行不确定)

  • 进程具有独立性,父子进程也是如此,对其中一个进程的修改不会影响另一个进程

  • 独立性体现在两方面:1、代码方面是可读的

2、数据方面,当一个执行流尝试修改数据时,OS会给我们的进程触发写时拷贝(后面章节详细讲解)。


end.

生活原本沉闷,但跑起来就会有风!🌹

相关文章:

【Linux】进程理解与学习Ⅰ-进程概念

环境&#xff1a;centos7.6&#xff0c;腾讯云服务器Linux文章都放在了专栏&#xff1a;【Linux】欢迎支持订阅&#x1f339;相关文章推荐&#xff1a;【Linux】冯.诺依曼体系结构与操作系统进程概念什么是进程&#xff1f;进程是什么&#xff1f;我们打开任务管理器可以看到有…...

WebKitX ActiveX 6.0 X86 Crack

WebKitX ActiveX将 Chromium Embedded Framework (CEF3) 包装到一个进程外的 ActiveX 组件中&#xff0c;以便与 OLE/COM 语言一起使用。Chromium Embedded Framework 封装了 WebKit Blink HTML5 Renderer 和 Google V8 JavaScript Engine。这是一个用于商业用途的生产级稳定组…...

开源项目:数据库表结构生成文档工具

目录 一、软件介绍 二、技术框架 三、功能介绍 四、代码展示 1、获取数据库信息部分代码 2、导出Html文档代码 五、运行效果 六、项目开源地址 一、软件介绍 今天给大家分享我自己编写的数据库表结构文档生成工具&#xff0c;方便大家在实际开发当中&#xff0c;可以很方便导出…...

spring的两种拦截器HandlerIntercepter和MethodIntercepter

介绍 Spring有两种拦截器提供给我们使用&#xff0c;一种是HandlerIntercepter&#xff0c;另一种是MethodIntercepter。这两种的来源不同&#xff0c;实现方式也不同&#xff0c;具体的下面来看一下。 HandlerIntercepter 来源 来源于spring-webmvc包 HandlerIntercepter拦…...

初级算法-字符串

主要记录算法和数据结构学习笔记&#xff0c;新的一年更上一层楼&#xff01; 初级算法-字符串一、反转字符串二、反转字符串&#xff08;二&#xff09;三、替换空格四、翻转字符串里的单词五、左旋转字符串六、实现 strStr()七、重复的子字符串字符串中元素只能是字符String…...

华为OD机试题 - 寻找目标字符串(JavaScript)| 机考必刷

更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为…...

删除Terminating状态的namespace:cattle-system

这里以cattle-system为例&#xff01;执行删除命令后namespace&#xff08;也是用其他k8s object&#xff09;仍然存在&#xff0c;首先执行 kubectl edit namespace cattle-system 查看是否存在spec.finalizers: kubernetes&#xff0c;如&#xff1a; spec: finalizers:…...

MiniOB 并发B+树实现解析

MiniOB 是 OceanBase 联合华中科技大学推出的一款用于教学的小型数据库系统&#xff0c;希望能够帮助数据库爱好者系统性的学习数据库原理与实战。 B 树介绍 B 树是传统数据库中常见的索引数据结构&#xff0c;比如MySQL、PostgreSQL都实现了B树索引。B 树是一个平衡多叉树&am…...

SpringCloud负载均衡服务调用——Ribbon

Ribbon 本专栏学习内容来自尚硅谷周阳老师的视频 有兴趣的小伙伴可以点击视频地址观看 简介 Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。 简单的说&#xff0c;Ribbon是Netflix发布的开源项目&#xff0c;主要功能是提供客户端的软件负载均衡算…...

各种邮箱服务软件对比

1.宝塔邮局管理器 特点:简单易用,可视化操作,小白也能搞,还有备份功能,一般足够用了 缺点:稳定性真是差,隔三差五的不能收发.没有接口,不能任意修改邮箱密码,只能管理员修改 注意要点:一定要开启ssl,否则有些邮箱给你发邮件你收不到 建议:不要入坑.坏了之后没法修复,哭都没地方…...

相机单独标定的实现过程[autoware标定]、tmp文件的查看方式

安装了autoware1.13和calibration标定包&#xff0c;发现实现相机单独标定的过程较为坎坷&#xff0c;参考了一些博主的方法&#xff0c;发现下面的过程更加适合自己&#xff0c;做个笔记。 1安装标定箱&#xff08;与calibration标定包的安装并不冲突&#xff09; 标定工具箱…...

4.10.1、IP 多播技术的相关基本概念

多播&#xff08;Multicast&#xff0c;也称为组播&#xff09;是一种实现 “一对多” 通信的技术&#xff0c;与传统单播“一对一”通信相比&#xff0c;多播可以极大地节省网络资源。 在因特网上进行的多播&#xff0c;称为 IP 多播。 1、单播 & 多播 如下所示&#xf…...

PIGOSS BSM监控国产数据库Oscar

前言神通数据库(原OSCAR数据库&#xff09;是天津神舟通用数据技术有限公司&#xff08;简称“神舟通用公司”&#xff09;拥有自主知识产权的企业级、大型通用关系型数据库管理系统。PIGOSS BSM作为网利友联科技完全自主研发的纯国产基础 IT 架构运行状态监测平台软件&#xf…...

Spring Boot中文件上传

Spring Boot中文件上传 前言 本篇主要参考Spring官方文档&#xff0c;整理了Spring Boot中文件上传如何实现&#xff0c;以及在代码中使用RestTemplate和HttpClient两种方式实现文件上传。 创建Spring Boot项目 首先创建一个Spring Boot Web项目&#xff0c;使用的Spring B…...

Github上传大文件(>25MB)教程

Github上传大文件&#xff08;>25MB&#xff09;教程Github上传大文件&#xff08;>25MB&#xff09;教程安装git安装Git Large File Storage实例踩坑点1&#xff1a;failed to push some refs to踩坑点2&#xff1a;main与master踩坑点3&#xff1a;Failed to connect t…...

面试官:mysql索引会缓存内存吗?

文章目录 InnoDB缓冲池如何设置方法一:使用 `innodb_buffer_pool_size` 变量方法二:修改my.ini配置文件InnoDB缓冲池 InnoDB存储引擎是基于磁盘存储表文件和索引的,并将数据按页的方式管理,由于访问磁盘的速度较慢,多次访问磁盘会造成数据库性能的下降,为此,InnoDB在内…...

bs4解析数据和csv文件

\b 检测所在的位置是否是单词边界&#xff08;任何可以将不同的单词进行区分的符号&#xff1a;空白符号&#xff0c;标点符号&#xff0c;字符串开头&#xff0c;字符串结尾&#xff09; ^ 检测是否是字符串开头 $ 检测是否是字符串结尾 csv保存数据 什么是csv文件 读操作…...

Linux中Buffer和Cache的区别

Linux中Buffer和Cache的区别 free命令中会有一项buff/cache, 通过man free可以看到这里的关于buff/cache的介绍 buff/cache包含两部分 buffers:内核缓存区用到的内存&#xff0c;对应/proc/meminfo中Buffers的值 cache:内核页缓存和Slab用到的内存&#xff0c;对应/proc/mem…...

Docker 镜像使用

目录 1、列出镜像列表 2、获取一个新的镜像 3、查找镜像 4、拖取镜像 5、删除镜像 6、创建镜像 a.更新镜像 b.构建镜像 设置镜像标签 当运行容器时&#xff0c;使用的镜像如果在本地中不存在&#xff0c;docker 就会自动从 docker 镜像仓库中下载&#xff0c;默认是从 …...

Java阶段一Day10

Java阶段一Day10 文章目录Java阶段一Day10抽象类和抽象方法接口案例小练习引用类型数组教师总结回顾&#xff1a;精华笔记&#xff1a;笔记&#xff1a;补充&#xff1a;抽象类和抽象方法 关键字&#xff1a;abstract 只有方法的定义&#xff0c;没有具体的实现&#xff08;连…...

触摸屏与PLC之间如何快速实现无线PPI通信?

PPI协议是西门子为S7-200专门开发的通信协议&#xff0c;是不开放的协议&#xff0c;CPU自带的两个通信口&#xff08;Port0&#xff0c;Port1&#xff09;均支持该协议&#xff0c;S7-200的一些通信模块也支持PPI协议。编程软件Micro/WIN与CPU进行编程通信也使用PPI协议&#…...

【华为OD机试 2023最新 】 羊、狼、农夫过河(C++ 100%)

题目描述 羊、狼、农夫都在岸边,当羊的数量小于狼的数量时,狼会攻击羊,农夫则会损失羊。农夫有一艘容量固定的船,能够承载固定数量的动物。 要求求出不损失羊情况下将全部羊和狼运到对岸需要的最小次数。 只计算农夫去对岸的次数,回程时农夫不会运送羊和狼。 备注:农…...

Java中关于try、catch、finally中的细节分析

本文讲解的是关于Java中关于try、catch、finally中一些问题 下面看一个例子&#xff08;例1&#xff09;&#xff0c;来讲解java里面中try、catch、finally的处理流程 public class TryCatchFinally {SuppressWarnings("finally")public static final String test(…...

Zookeeper原理

一、概念 Zookeeper是一个开源的、分布式的&#xff0c;为分布式应用提供协调服务的Apache项目。封装好复杂易出错的关键服务&#xff0c;将简单易用的接口和性能高效、功能稳定的系统提供给用户。 二、选举机制 首先是几个概念&#xff1a; myid&#xff1a;节点的唯一标识&…...

关于FPGA如何快速生成模块的例化模板(实用)

关于FPGA如何快速生成模块的例化模板&#xff08;实用&#xff09; 语言 &#xff1a;Verilg HDL 、VHDL EDA工具&#xff1a;ISE、Vivado、Quartus II 关于FPGA如何快速生成模块的例化模板&#xff08;实用&#xff09;一、引言二、快速生成例化模块的几种方法1. IP核的例化模…...

在 Python 中将字符串转换为集合

使用 set() 类将字符串转换为集合&#xff0c;例如 my_set set(my_str)。 set() 类将通过拆分其字符将字符串转换为集合。 my_str one# ✅ 通过拆分字符将字符串转换为集合 my_set set(my_str) print(my_set) # &#x1f449;️ {n, o, e}# -----------------------------…...

大数据Flink进阶(十三):Flink 任务提交模式

文章目录 Flink 任务提交模式 一、会话模式&#xff08;Session Mode&#xff09; 二、单作业模式&#xff08;Per-Job Mode&#xff09; 三、应用模式&#xff08;Application Mode&#xff09; Flink 任务提交模式 Flink分布式计算框架可以基于多种模式部署&#xff0c;…...

day11—编程题

文章目录1.第一题1.1题目1.2涉及的相关知识1.3思路1.4解题2.第二题2.1题目2.2思路2.3解题1.第一题 1.1题目 描述&#xff1a; 将一棵无穷大满二叉树的结点按根结点一层一层地从左往右编号&#xff0c;根结点编号为1。现给定a&#xff0c;b为两个结点。设计一个算法&#xff0…...

CentOS下安装crontab及cron表达式解析

目录安装依赖服务启停任务操作参数简要说明1、参数说明2、cron表达式解析(1)定义(2)结构(3)字段含义(4)注意事项(5)常用表达式例子crontab示例结尾安装依赖 # vixie-cron软件包是crontab的主程序 # crontabs软件包是用来安装、卸装、或列举用来驱动crontab守护进程的表格的程序…...

python 绘制训练曲线--基于Numpy.convolve曲线平均滤波

文章目录1 训练曲线--震荡的非常厉害2 基于Numpy.convolve曲线平均滤波3 python 绘制训练曲线 平滑处理--Savitzky-Golay 滤波器曲线平滑4 python 绘制训练曲线--插值法 曲线平滑处理1 训练曲线–震荡的非常厉害 上一篇文章用python自己绘制训练曲线震荡的非常厉害&#xff08…...