前言:
大家好,我是良辰丫,今天我们来认识一下进程的相关概念,当接触到进程,也就意味着我们进入了javaEE的学习阶段,这篇文章主要带大家去学习一些面试题,帮助大家更好的去学习并熟悉进程,跟着我的步伐一起进入学习吧!!!💞💞💞
🧑个人主页:良辰针不戳
📖所属专栏:javaEE初阶
🍎励志语句:生活也许会让我们遍体鳞伤,但最终这些伤口会成为我们一辈子的财富。
💦期待大家三连,关注,点赞,收藏。
💌作者能力有限,可能也会出错,欢迎大家指正。
💞愿与君为伴,共探Java汪洋大海。

目录
所谓进程,可以这样理解,一个运行起来的程序就叫进程.也可以把程序比作一个工厂,工厂正在加工运转的即进程.
每个应用程序运行于现代操作系统之上时,操作系统会提供一种抽象,好像系统上只有这个程序在运
行,所有的硬件资源都被这个程序在使用。这种假象是通过抽象了一个进程的概念来完成的,进程可以说是计算机科学中最重要和最成功的概念之一。
进程是操作系统对一个正在运行的程序的一种抽象,换言之,可以把进程看做程序的一次运行过程;同时,在操作系统内部,进程又是操作系统进行资源分配的基本单位。
后缀名为exe的文件叫做可执行文件,在没有点击它运行之前,它只能叫做程序,当我们点击它之后,在它运行的时候,我们就给它有了新的定义,叫做进程.

进程运行的时候需要向操作系统申请资源,需要反复强调的一句话是进程是操作系统进行资源分配的基本单位,此处涉及的资源包括内存,硬盘,CPU等.
pid: 进程的唯一标识,相当于一个人的身份证号码.内存指针: 当前内容使用的内存是那一部分(表示地址指向),进程要跑起来就需要消耗一定的硬件资源,比如内存.文件描述符表: 硬盘上存储的数据,就是以文件为单位进行整理的,进程每次打开一个文件,就会产生一个文件描述符(标识了这个被打开的文件),一个进程可能会打开许多文件,对应了一组文件描述符,把这样的文件描述符放到一个顺序表这样的结构里面,就构成了所谓的文件描述符.这标识着进程运行的时候使用了哪些硬盘上的资源.进程关联的程序信息,例如哪个程序,加载到内存中的区域等分配给该资源使用的各个资源
程序之所以能运行,全依靠CPU,每个程序,其实就是一组二进制指令的集合,那么我们简单认识一下CPU.
cpu中文名叫中央处理器(Central Processing Unit,简称CPU),是计算机系统的运算和控制核心,是信息处理、程序运行的最终执行单元。CPU是人类科技史上最伟大的成就之一.
进程有许多运行状态,我们主要了解两个状态.
就绪状态: 进程已经准备好,随时可以在CPU上执行.阻塞状态: 该进程无法在CPU上执行.
简单了解一下上面两个状态,加入你有一个好朋友A,你们两个约好一起去旅游,但是暂时没有定时间,A也没有其它的事情要干,当你要去旅游的时候,你可以随叫随到,这就相当于就绪状态;你还有一个好朋友B,因为一些特殊的情况,他出差了,你们曾经约定可以一起旅行,但是可能暂时做不到了,这就是所谓的阻塞状态.
进程是具有一定的优先级的,在CPU上规定了一系列对进程的优先级约束,比如先来先服务就是按照哪个进程先执行,另一个进程进入阻塞状态.按照优先级的次序进行执行.
所谓上下文,就是描述了进程执行到哪里的存档信息,进程在离开CPU的时候要对当前进程运行的中间结果进行存档,等下次进程回到CPU的时候恢复之前的存档,从上次的结果继续向后执行,这样就不会后台退出,比如王者农药这个游戏,我们挂着后台回复一个消息或者干一些别的事情,我们回到王者,后台依然存在.
- 如果进程结束了,就不必进行存档.
- 在进程中理解上下文,进程在运行的过程中,CPU内部的一系列寄存器的值,其中,寄存器的作用有很多,我们需要记得的是寄存器用来保存当前进程执行的中间结果,包括进程运行到哪一条指令.
存档,就是进程在离开CPU的时候,就需要把这些寄存器的值存到PCB的上下文字段中;读档,进程下次回到CPU,再把PCB的值恢复到寄存器中.
并行: 同一个时刻,两个核心同时执行两个进程,此时这两个进程就是并行执行的(一起执行).并行可以理解为两个人分别一起做两件事情.
并发: 一个核心,先执行进程1,执行一会再执行进程2,执行一会儿进程2之后再执行进程3…然后再返回来执行进程1,一会再执行进程2…只要切换的速度快,在我们肉眼看来其实和并行没有什么区别(可以简单的认为同时执行).
很多情况下操作系统的任务通过并行和并发两种方式共同完成的,我们通常把并行+并发的方式统称为并发.当一个核心(主体)并发执行几万甚至几十万个任务的时候,我们把它叫做高并发.
统计每个进程在CPU上执行了多久,可作为进程调度的参考依据.比如在CPU中三个进程ABC,可能进程A执行时间比较少,我们就可以多给它分配一些执行时间.
操作系统往往通过双向链表组织PCB
- 创建一个进程就是创建一个链表节点.
- 销毁一个进程就是销毁一个链表节点.
- 遍历进程就是遍历进程链表.
操作系统对内存资源的分配,采用的是空间模式 —— 不同进程使用内存中的不同区域,互相之间不会干扰.操作系统给资源分配的内存,是以虚拟地址空间的方式进行分配的,每个进程访问的内存地址,其实并不是真正的内存地址.
下面是进程直接访问物理内存地址,此时可能产生问题,如果进程A奔溃了,会把同一内存条上的其它进程也搞奔溃.这就对于操作系统的稳定性产生了一定的挑战.

那么,什么是
稳定性,可以简单的认为,两个相关联的东西,其中一个坏掉了导致另外一个不能运行,这就是说明这两个相关联的东西形成的整体稳定性较差;反之,如果没有较大的影响,我们就说这个整体稳定性较好.

上面两个进程中,通过代码操控自己要访问的物理内存地址,访问的内存会被操作系统自动映射到真正的物理内存上,但是进程自身感知不到真正的物理内存地址是什么.此时进程A奔溃了就不会影响进程B,因为任何一个内存操作都需要通过页表来进行翻译,如果出现野指针,野指针的地址会与页表上的地址进行对比,如果页表上没有这个地址将无法翻译,也就无法访问并修改物理内存,因此呢,也不会对别的进程造成干扰.
这样可以有效的校验,校验当前的地址是否有效.一个进程无法干预另一个进程的内存,表示了每个进程有自己独立的地址空间.这样大大提高了操作系统的稳定性.
有些时候进程之间需要相互配合,交互运行.
如果每个进程可以直接访问物理内存(没有隔离性),也就不需要进程通信,进程A直接把结果写到进程B的内存中就可以了.
所谓进程通信,就是在隔离性的前提下,找一个公共区域,让两个进程借助这个公共区域完成进程间的数据交换.- 操作系统提供的进程间通信方式有很多种,有管道,消息队列,共享内存,信号等.
- 在java中,我们主要使用文件和socket这两种方式完成进程通信(后续详解).
后序:
今天我们有关的内容就到这里了,我们学习了进程的一些相关概念,学习了进程控制块,进程一些属性等内容,希望本篇小小的文章可以帮到大家💌💌💌
在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',
我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
文章目录git常用命令(简介,详细参数往下看)Git提交代码步骤gitpullgitstatusgitaddgitcommitgitpushgit代码冲突合并问题方法一:放弃本地代码方法二:合并代码常用命令以及详细参数gitadd将文件添加到仓库:gitdiff比较文件异同gitlog查看历史记录gitreset代码回滚版本库相关操作远程仓库相关操作分支相关操作创建分支查看分支:gitbranch合并分支:gitmerge删除分支:gitbranch-ddev查看分支合并图:gitlog–graph–pretty=oneline–abbrev-commit撤消某次提交git用户名密码相关配置g
我明白了:x,(y,z)=1,*[2,3]x#=>1y#=>2z#=>nil我想知道为什么z的值为nil。 最佳答案 x,(y,z)=1,*[2,3]右侧的splat*是内联扩展的,所以它等同于:x,(y,z)=1,2,3左边带括号的列表被视为嵌套赋值,所以它等价于:x=1y,z=23被丢弃,而z被分配给nil。 关于ruby-带括号和splat运算符的并行赋值,我们在StackOverflow上找到一个类似的问题: https://stackoverflow
我正在尝试使用以下代码通过将ffmpeg实用程序作为子进程运行并获取其输出并解析它来确定视频分辨率:IO.popen'ffmpeg-i'+path_to_filedo|ffmpegIO|#myparsegoeshereend...但是ffmpeg输出仍然连接到标准输出并且ffmepgIO.readlines是空的。ffmpeg实用程序是否需要一些特殊处理?或者还有其他方法可以获得ffmpeg输出吗?我在WinXP和FedoraLinux下测试了这段代码-结果是一样的。 最佳答案 要跟进mouviciel的评论,您需要使用类似pope
假设您在Ruby中执行此操作:ar=[1,2]x,y=ar然后,x==1和y==2。是否有一种方法可以在我自己的类中定义,从而产生相同的效果?例如rb=AllYourCode.newx,y=rb到目前为止,对于这样的赋值,我所能做的就是使x==rb和y=nil。Python有这样一个特性:>>>classFoo:...def__iter__(self):...returniter([1,2])...>>>x,y=Foo()>>>x1>>>y2 最佳答案 是的。定义#to_ary。这将使您的对象被视为要分配的数组。irb>o=Obje
我目前正在用Ruby编写一个项目,它使用ActiveRecordgem进行数据库交互,我正在尝试使用ActiveRecord::Base.logger记录所有数据库事件具有以下代码的属性ActiveRecord::Base.logger=Logger.new(File.open('logs/database.log','a'))这适用于迁移等(出于某种原因似乎需要启用日志记录,因为它在禁用时会出现NilClass错误)但是当我尝试运行包含调用ActiveRecord对象的线程守护程序的项目时脚本失败并出现以下错误/System/Library/Frameworks/Ruby.frame
我想从rubyrake脚本运行一个可执行文件,比如foo.exe我希望将foo.exe的STDOUT和STDERR输出直接写入我正在运行rake任务的控制台.当进程完成时,我想将退出代码捕获到一个变量中。我如何实现这一目标?我一直在玩backticks、process.spawn、system但我无法获得我想要的所有行为,只有部分更新:我在Windows上,在标准命令提示符下,而不是cygwin 最佳答案 system获取您想要的STDOUT行为。它还返回true作为零退出代码,这可能很有用。$?填充了有关最后一次system调
我正在构建一个应用程序,想知道是否将未使用的对象设置为nil是生产级编码中的常见做法。我知道这只是垃圾收集器的提示,并不总是处理对象。 最佳答案 根据这个thread如果您使用完一个成员对象,将其设置为nil将引发被引用对象被垃圾回收。如果它是局部变量,方法exit将做同样的事情。也就是说,如果您要求将成员显式设置为nil,我会质疑您的设计。 关于ruby-将对象设置为nil是否很常见?,我们在StackOverflow上找到一个类似的问题: https://