【Linux进行时】进程概念

在这里插入图片描述

进程的概念

什么是进程呢?

❓首先我们需要认识一下什么叫进程呢?

image-20230811183505468

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

上图我们发现进程是一个个可执行程序!

所有,我们以前的任何启动并运行程序的行为——由操作系统帮助我们将程序转换为进程——完成特定的任务

可执行程序(.exe)本质就是一个普通的二进制文件

❓文件是什么呢? 💡文件等于内容+属性

image-20230418164722723

这个一个个可执行程序(进程)就像我们学生在学校中被管理一样

❓当可执行程序有很多个,都加载到进程里面,那当有成百上千的可执行程序加载到进程,那操作系统会管吗?

❓会管,所以操作系统如何管理进程?

🔥在计算机中,在操作系统内核 里面,要为每个进程加载到内存的时候,操作系统会帮我们创建一个数据结构对象,这个东西在操作系统教材叫pcb,在Linux中叫task_struct

image-20230418165839540

这个结构体提取了所有进程的属性

🔥这里的结构体一个个都是独立,因此可以有结构体指针,可以让pcb直接关联起来,就像链表一样

操作系统,要将其中一个进程结束,将其释放它的代码和数据,和task_struct

❓如果想要执行一个优先级最高的要怎么做呢?

🔥因为pcb是用链表的形式,因此我们可以通过pcb的链表找到优先级最高的地方,然后通过pcb找到进程的代码和数据,将这个进程加载到CPU

现在我们新增加一个进程到内存,然后操作系统要管理进程,因此给你创建了一个pcb,因此对进程的管理就变成了对pcb的管理image-20230418171046084

🔥一般pcb和代码和数据加起来才可以被叫做进程image-20230418171529764

🔥什么是进程:进程=内核关于进程的相关数据结构+当前进程的代码和数据

❓为什么进程管理中需要pcb?

因为我们要管理进程,pcb就是一个struct结构体

image-20230419200616072

Makefile

myprocess:myprocess.c
	gcc -o myprocess myprocess.c
.PHONY:clean
clean:
	rm -f myprocess.c

myprocess.c

#include<stdio.h>
#include<unistd.h>
int main()
{
  while(1)
  {
    printf("hello process\n");
    sleep(1);
  }
  return 0;
}

image-20230419202454022

这个./就是将可执行程序加载到内存,就做进程,也就是生成了pcb

image-20230419202629638


ps axj指令

🔥ps axj是查看当前所有的进程,通过管道过滤出我的进程

image-20230812095102007

🔥head -1是把对应的第一个TST界面的输出结果的第一行拿到

image-20230419212528377

🔥拿到属性名

image-20230419212629444

这里的逻辑与是先做完前面的,再做后面的

image-20230419212755100

❓这里这个是什么东西啊?grep自己也就一个进程,如果我们只想看到我们自己的进程,不想看到grep进程呢?

image-20230419213001386

我们这里再开一次渠道,也执行可执行程序

image-20230419213202993

查询/proc

一个进程运行起来都有一个对应的一个PID,除了我们用一些指令查看已经运行的进程以外,我们还可以再系统根目录下的proc目录

image-20230419213710924

proc跟普通文件不一样,他是内存级的文件系统,只有当操作系统的启动才有,我们平常的时候没有

image-20230419214003601

这里很明显,这里用数字命名的都是目录,都是d开头的,特定进程的PID

❓特定进程的pid又是什么呢

image-20230419214249620

🔥我们的进程创建后了后,我们的操作系统会自动的在/proc目录下以我们新增的进程的pid命名的

如果我们的进程删掉了呢?,也就是中止进程

image-20230419214633401

我们会发现我们不能查看了,根本原因就是操作系统会自动把那个文件夹删除回收

父子进程

❓如何查询pid?
ps axj | head -1 && ps axj | grep myprocess | grep myprocess | grep -v grep

image-20230419220614197

中止掉后,那个进程就没有了

image-20230419220727077

❓如何我们自己获取一下进程的pid,来证明程序运行起来就是经常呢?

man getpid一下

image-20230419221132903

返回类型是pid_t,这个类型是操作系统的类型就是一个有符号整数

更改一下myprocess.c

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{
  while(1)
  {
    printf("hello process,我是一个进程,我的pid是:%d\n",getpid());
    sleep(1);
  }
  return 0;
}

image-20230419222324648

Ctrl+c可以中止进程

man getppid一下

image-20230420212345918

查看父进程pid

🔥我们发现getpid是查询子进程pid,getppid是查看父进程pid

 1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<sys/types.h>
  4 int main()
  5 {
  6   while(1)
  7   {
  8     printf("hello process,我是一个进程,我的pid是:%d\n,我的父进程pid为:%d\n",getpid(),getp    pid());
  9     sleep(1);                                                                              
 10   }                                                                        
 11   return 0;                                                                
 12 }            

image-20230420212940662

❓我们发现就算我们中止一次,虽然我们进程会变,但是我们的父进程基本上不变,这是为什么呢?

我们找一下这个父进程,父进程pid:31059

image-20230420213216078

我们要找的不是与31059相关的,而是就是31059的

ps ajx | head -1 && ps ajx | grep 31059

image-20230420213404837

🔥bash命令行解释器,本质上也是一个进程

❓命令行启动的所有的程序,最终都会变成进程,而该进程对应的父进程都是bash(如何做到的呢?)

❓如果我们不想用Ctrl+c中止,我们可以用什么中止呢?

killed -9 对应的pid

❓如何创建的子进程呢?

man forkz,这个fork后面会详细讲,先用用

🔥fork函数

image-20230420214916223

修改一下myprocess.c

🔥批量注释:Ctrl+v变为视图模式,然后按j向下选中区域,然后按切换为大写模式,按i,然后写//

image-20230420215350949

❓如何批量取消注释

🔥Ctrl+v ,l选中区域,然后d就可以了

 #include<stdio.h>
 #include<unistd.h>
 #include<sys/types.h>
 int main()
  {

    printf("AAAAAAAAAAAAAAAAAAAAAAAAA\n");
   fork();
   printf("BBBBBBBBBBBBBBBBBBBBBBBBB\n");
   sleep(1);                                                                                          
   return 0;
} 

image-20230420220126114

❓这是为什么呢?

image-20230420220413019

🔥谁调pid那就获得谁的pid,说明这是两个进程,这是父子进程,A是第一个进程(也就是第二行那个)

man fork

创建子进程fork

image-20230420221101756

修改一下myprocess.c

#include<stdio.h>
 #include<unistd.h>
#include<sys/types.h>
 int main()
{ printf("AAAAAAAAAAAAAAAAAAAAAAAAA:父进程是%d,子进程是%d\n",getppid(),getpid());
id_t ret= fork();
 printf("BBBBBBBBBBBBBBBBBBBBBBBBB:父进程是%d,子进程是%d,ret=%d,&ret=%p\n",getppid(),getpid      (),ret,&ret);
sleep(1);
return 0;
}

image-20230420222057496

❓为什么fork有两个返回值?

一个是父进程的,一个是子进程的

❓为什么一个变量里面地址一样,读取的数据内容不一样呢?

父子进程是独立的

我们一般不会像上面那样写fork,我们来看一个正常情况下的,

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

  }
  return 0;
}

image-20230420230158734

❓如何参加子进程呢?

🔥fork就可以

  • fork之后,执行流会变成两个执行流

  • fork之后,谁先运行由调度器决定

  • fork之后,fork之后的代码共享,通常我们通过if和else if来进行执行分流

🔑详细解析:

原理:fork如何看待代码和数据?

进程运行的时候,是具有独立性的,父子进程也是一样

int main()
{
  pid_t ret=fork();
  int x=100;
  if(ret==0)
  {
    while(1)
    {
      printf("我是子进程,我的pid是%d,我的父进程是%d,%d,%p\n",getpid(),getppid(),x,&x);
      sleep(1);
    }
  }
  else if(ret>0)
  {
    while(1)
    {
      printf("我是父进程,我的pid是%d,我的父进程是:%d,%d,%p\n",getpid(),getppid(),x,&x);
    sleep(1);
    }
  }
  else{

  }
  return 0;
}

image-20230421161247175

int main()
{
  pid_t ret=fork();
  int x=100;
  if(ret==0)
  {
    while(1)
    {
      printf("我是子进程,我的pid是%d,我的父进程是%d,%d,%p\n",getpid(),getppid(),x,&x);
      sleep(1);
    }
  }
  else if(ret>0)
  {
    while(1)
    {
      printf("我是父进程,我的pid是%d,我的父进程是:%d,%d,%p\n",getpid(),getppid(),x,&x);
      x=4237sleep(1);
    }
  }
  else{

  }
  return 0;
}

image-20230421161427623

我们发现父进程的x改了,但是子进程没有!!!

这个情况跟我们刚刚fork返回值不一样的情况一样

image-20230421161710284

写时拷贝,也就是只更改写的时候的情况,不改变读的情况

fork如何理解两个返回值问题

fork调用本质上就是操作系统OS提供的一个函数

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot06---前端路由VueRouter

单页面应用&#xff0c;意思是只有一个html&#xff0c;变化的内容是不同组件进行切换&#xff0c;每个组件加载网络请求&#xff0c;渲染对应的数据&#xff0c;这个内容就是学习怎么完成组件切换 以网易云音乐为例&#xff1a; 网易云音乐 (163.com) 现在无需注册&#xf…

springBoot的日志文件

日志是程序的重要组成部分&#xff0c;主要可以用来定位和排查问题。除此之外&#xff0c;还可以用来&#xff1a; 1. 记录用户的登录日志&#xff0c;方便分析用户是正常登录还是恶意破解&#xff1b; 2. 记录系统的操作日志&#xff0c;方便数据恢复和定位操作人&#xff1b;…

docker 安装elasticsearch、kibana

下载es镜像 docker pull elasticsearch 启动es容器 docker run --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.typesingle-node" -e ES_JAVA_OPTS"-Xms512m -Xmx512m" -d elasticsearch 验证es界面访问 ​​​​​http://节点ip:9200/ ​…

leetcode 416. 分割等和子集

2023.8.12 太难了ToT.... 一题做了一个下午。 本题是动规题目的0-1背包问题系列。将分割子集转化为 在nums数组中任取任意元素使其和等于总元素和的一半&#xff0c;即可满足题目条件。 1、使用一个bool型二维dp数组&#xff0c;dp[i][j] 的含义是&#xff1a;任取nums数组在索…

已有公司将ChatGPT集成到客服中心以增强用户体验

Ozonetel正在利用ChatGPT来改善客户体验。该公司表示&#xff0c;他们通过使用ChatGPT收集与客户互动过程收集的“语料”能够更有针对性地提高服务效率&#xff0c;提供个性化的用户体验&#xff0c;并实现更高的客户满意度。[1] 通过这套解决方案&#xff0c;客服中心将拥有一…

27.Netty源码之FastThreadLocal

highlight: arduino-light FastThreadLocal FastThreadLocal 的实现与 ThreadLocal 非常类似&#xff0c;Netty 为 FastThreadLocal 量身打造了 FastThreadLocalThread 和 InternalThreadLocalMap 两个重要的类。下面我们看下这两个类是如何实现的。 FastThreadLocalThread 是对…

c++文件流详细笔记

c++流 IO :向设备输入数据和输出数据 C++的IO流 设备: 文件控制台特定的数据类型(stringstream)c++中,必须通过特定的已经定义好的类, 来处理IO(输入输出) 文件流 文件流: 对文件进行读写操作 头文件: 类库: ifstream 对文件输入(读文件) ofstream 对文件输出(写…

idea中如何处理飘红提示

idea中如何处理飘红提示 在写sql时&#xff0c;总是会提示各种错误 查找资料&#xff0c;大部分都是说关提示&#xff0c;这里把错误提示选择为None即可 关掉以后&#xff0c;也确实不显示任何提示了&#xff0c;但总有一种掩耳盗铃的感觉 这个sms表明明存在&#xff0c;但是还…

深度学习常用的python库学习笔记

文章目录 数据分析四剑客Numpyndarray数组和标量之间的运算基本的索引和切片数学和统计方法线性代数 PandasMatplotlibPIL 数据分析四剑客 Numpy Numpy中文网 ndarray 数组和标量之间的运算 基本的索引和切片 数学和统计方法 线性代数 Pandas Pandas中文网 Matplotlib Mat…

MuMu模拟器运行一段时间后Device.Present耗时突然上升

1&#xff09;MuMu模拟器运行一段时间后Device.Present耗时突然上升 2&#xff09;​如何在运行过程中获得温度信息 3&#xff09;Input System鼠标更换主按键的Bug 4&#xff09;如何禁止Unity向https://config.uca.cloud.unity3d.com发送设备信息 这是第347篇UWA技术知识分享…

Leetcode-每日一题【剑指 Offer 26. 树的子结构】

题目 输入两棵二叉树A和B&#xff0c;判断B是不是A的子结构。(约定空树不是任意一个树的子结构) B是A的子结构&#xff0c; 即 A中有出现和B相同的结构和节点值。 例如: 给定的树 A: 3 / \ 4 5 / \ 1 2 给定的树 B&#xff1a; 4 / 1 返回 true&#xff0…

C++笔记之静态成员函数的使用场景

C笔记之静态成员函数的使用场景 C静态成员函数的核心特点是不与特定类实例相关&#xff0c;可通过类名直接调用&#xff0c;用于执行与类相关的操作而无需创建类对象。其主要用途是在类级别上共享功能&#xff0c;管理全局状态或提供工具函数。 code review! 文章目录 C笔记之…

悬崖传感器调试问题总结

悬崖传感器原理 使用ADC采样电路&#xff0c;周期的进行开/关灯&#xff0c;获取ADC采样值。根据预先设置好ADC门限&#xff0c;判断是否为悬崖。ADC的精度是12位&#xff0c;对应电路的电压是3.3伏&#xff0c;悬崖传感器通过开灯和关灯&#xff0c;接收的不同灯光强度&#x…

[数据集][目标检测]道路坑洼目标检测数据集VOC格式1510张2类别

数据集格式&#xff1a;Pascal VOC格式(不包含分割路径的txt文件和yolo格式的txt文件&#xff0c;仅仅包含jpg图片和对应的xml) 图片数量(jpg文件个数)&#xff1a;1510 标注数量(xml文件个数)&#xff1a;1510 标注类别数&#xff1a;2 标注类别名称:["keng","…

Redis缓存设计

缓存能够有效地加速应用的读写速度&#xff0c;同时也可以降低后端负载&#xff0c;对日常应用的开发至关重要。但是将缓存加入应用架构后也会带来一些问题&#xff0c;本文将针对这些问题介绍缓存使用技巧和设计方案。 1缓存的收益和成本 下图左侧为客户端直接调用存储层的架…

vector【1】介绍与使用(超详解哦)

vector 引言vector介绍接口使用默认成员函数迭代器容量元素访问数据修改 总结 引言 在string部分&#xff0c;我们详细的介绍了各个接口的使用&#xff0c;虽然其不属于STL的一部分&#xff0c;但是接口与STL中的容器相似&#xff0c;所以我们在学习使用vector等STL容器的使用…

JavaScript之BOM+window对象+定时器+location,navigator,history对象

一.BOM概述 BOM即浏览器对象模型,它提供了独立于内容而与窗口进行交互的对象 BOM的顶级对象是window 二.window对象的常见事件 1.窗口加载事件window.onload window.onload function(){} 或者 window.addEventListener("onload" , function(){}); window.onlo…

websocket知识点

http协议 http协议特点&#xff1a; 无状态协议每个请求是独立的单双工通信&#xff0c;且服务器无法主动给客户端发信息http协议受浏览器同源策略影响 http实现双向通信方法: 轮询长轮询iframe流sse EventSource websocket协议 websocket协议: 全双工协议支持跨域支持多…

近地面无人机植被定量遥感与生理参数反演技术

遥感&#xff08;RS-Remote Sensing&#xff09;——不接触物体本身&#xff0c;用传感器收集目标物的电磁波信息&#xff0c;经处理、分析后&#xff0c;识别目标物&#xff0c;揭示其几何、物理性质和相互关系及其变化规律的现代科学技术。 换言之&#xff0c;即是“遥远的感…

【Ubuntu】简化反向代理和个性化标签页体验

本文将介绍如何使用Docker部署Nginx Proxy Manager和OneNav&#xff0c;两个功能强大且易用的工具。Nginx Proxy Manager用于简化和管理Nginx反向代理服务器的配置&#xff0c;而OneNav则提供个性化的新标签页体验和导航功能。通过本文的指导&#xff0c;您将学习如何安装和配置…
最新文章