文章目录
在前面我们学习了Liunx的基本指令和权限相关知识,还有基本工具的使用,有了以上的基础知识我们本章将正式接触操作系统,搬好小板凳要开讲了🙋🙋🙋……
我们常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系。

出了内存之外剩下的就是外设了~
为什么要有内存?
如果冯诺依曼体系结构中没有内存的话:
当整个体系结构加上内存之后:
补充:
为什么???
具体解释:
数据在流动的时候,从输入到内存,从内存到CPU,CPU计算处理完,将结果写回内存,然后定期再刷新到外设。
补充:
内存的存在可以去适配外设和CPU之间速度不匹配的问题,因为内存的存在可以去预先装载一些常见的内存管理软件,数据管理软件,就可以将数据以预加载的方式提前放在存储器当中,以提高中央处理器读取效率,就可以让我们以较高的效率完成计算和存储的任务。
先描述再组织,用C语言或C++描述,用数据结构组织数据。管理的本质对数据做管理 --> 对数据的管理 --> 对某种数据结构的管理 --> 对数据结构的各种操作,增删查改。
重点:
其实操作系统是一款软件,是一款专门搞管理的软件,软件可以管理软件,就像人可以管理人一样~
进程是一个运行起来的程序。
一般书上都会那么说,真的让人理解起来一头雾水,脑子里一篇空白😓😓😓,进程和程序的区别是什么?一个跑一个没跑,这是用形容词描述的,用名词怎么描述??
下面我们来慢慢讲🙋🙋🙋……
首先我们要知道,程序是个文件,是存在磁盘上的,然后不能简单的认为,将程序从磁盘加载到内存,这个程序就是进程了,就像随便一个人进入学校不能够称之为学生一样。
再者我们要知道,操作系统里面可能同时存在大量的进程!
操作系统要不要将所有的进程管理起来呢?答案是肯定的!
对进程的管理,本质是不是就是对进程数据的管理?答案是肯定的!
那我们对进程的管理,核心是不是:先描述,再组织呢?答案是肯定的!
PCB(proccess ctrl block):
Linux中的task_struct是一款具体的PCB当一个程序加载到内存时候,不仅仅是将代码和数据加载到内存,操作系统还要为了管理该进程创建对应的数据结构。

有大量的进程就必须把进程先描述再组织起来,把进程组织起来实际上是把描述进程的进程控制块组织起来。
那我们学习进程到底学的是什么呢?
第一阶段对进程的理解总结:
- 当一个程序从磁盘加载到内存,将代码和数据加载到内存只是第一步,第二步,操作系统为了管理这个进程,需要为该进程创建对应的描述该进程的进程控制块PCB,Liunx 下叫task struct。
- 只要在内存当中被操作系统管理,操作系统实际管的根本不是代码和数据,而是管的则是进程的PCB结构体。
- 第一阶段进程的理解:程序加载到内存之后的代码和数据,以及操作系统为了管理进程,所生成的描述进程的进程控制块PCB结构体(内核数据结构 + 代码和数据,这二者合起来,叫做进程)。
- 一个进程有一个PCB描述起来了,系统中有大量的PCB,只需要将系统中的PCB用数据结构组织起来,对应的对进程的管理就变成了对数据结构的增删查改。

计算机和OS设计出来就是为了给人们服务的,那么是如何给我们提供服务的呢?
我们调用printf函数向显示器打印,显示器是硬件,所谓的打印,本质就是将数据写到硬件上,那我们写的C语言能直接访问硬件吗?
操作系统是不相信任何人的要防止少数人,又要给多数人提供服务,所以操作系统是通过给用户提供接口的方式为用户提供服务的~
Linux操作系统是用C语言写的,这里所谓的“接口”,本质就是C函数!
我们学习系统编程本质就是在学习这里的系统接口。
我们如何调用系统调用接口:

要是小白的话,我们可以通过图形化界面或者是命令行指令来调用系统接口,在我们日常的生活中,安装卸载软件、本质就将各种资源拷贝到本地磁盘目录下,下载还用了网卡。我们只是用了图形化界面点击了一下,这就是管理操作。
要是初级工程师,就像正在学习的我们,会调用C语言的printf函数来将内容打印到显示器上,但是我们并没有自己实现printf函数,但是我们清楚地知道:
此时上层用中就可以做管理工作,开发工作,命令行操作。
补充:
那么我们之前学习的各种指令,执行指令也是进程。

通过ps指令,后面的axj几个选项的顺序无所谓,这是显示所有的进程。
我们写一个简单的死循环然他一直在跑,我们来查看一下它的进程~
结合我们之前学的指令,我们可以查看指定的进程:

我们调用了grep指令,所以这里查看进程的时候也是能显示grep进程的。
显示出前五行:

只显示要查看的进程:

只要匹配到-v后面的关键字一律不显示。
Windows下是通过双击打开一个进程, 而Linux则是通过./启动,在系统中找到可执行程序启动,这两者在系统层面上一模一样~
Linux的根目录下有个proc目录里面放的就是实时的进程:

proc:process,内存文件系统,里面放的是当前系统实时的进程信息。
查看进程的ID:

既然proc里面存的是实时的进程,那么我们就可以查到当前正在跑的进程:

当我们将刚刚的进程结束掉之后,再次执行以下mytest这个可执行程序,我们发现进程的ID发生了变化:

所以重启之后就是一个新的进程了。
我们在proc中打开这个进程,可以查看它的详细属性:

在我们之前学习C / C++语言的时候,我们就只是肤浅的理解当路径就是源文件所在的路径。
事实真的是这样吗??
答案并不是!!!
我们用ls -al选项来在proce目录中对应的进程中看一下它的更详细的属性:

我们可以看到进程当前的工作路径,和进程所对应的可执行程序在磁盘上所对应的位置。
我们在源文件代码中加一个新建文件的语句,目的就是看看当前路径到底是指的什么:
同时我们还将可执行文件移出当前路径:

我们再将程序跑起来:

在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中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是
我正在尝试使用以下代码通过将ffmpeg实用程序作为子进程运行并获取其输出并解析它来确定视频分辨率:IO.popen'ffmpeg-i'+path_to_filedo|ffmpegIO|#myparsegoeshereend...但是ffmpeg输出仍然连接到标准输出并且ffmepgIO.readlines是空的。ffmpeg实用程序是否需要一些特殊处理?或者还有其他方法可以获得ffmpeg输出吗?我在WinXP和FedoraLinux下测试了这段代码-结果是一样的。 最佳答案 要跟进mouviciel的评论,您需要使用类似pope
我目前正在用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调
A/ctohttp://wiki.nginx.org/CoreModule#usermaster进程曾经以root用户运行,是否可以以不同的用户运行nginxmaster进程? 最佳答案 只需以非root身份运行init脚本(即/etc/init.d/nginxstart),就可以用不同的用户运行nginxmaster进程。如果这真的是你想要做的,你将需要确保日志和pid目录(通常是/var/log/nginx&/var/run/nginx.pid)对该用户是可写的,并且您所有的listen调用都是针对大于1024的端口(因为绑定(
我有一个应用程序正在从Ruby迁移到JRuby(由于需要通过Java提供更好的Web服务安全支持)。我使用的gem之一是daemons创建后台作业。问题在于它使用fork+exec来创建后台进程,但这对JRuby来说是禁忌。那么-是否有用于创建后台作业的替代gem/wrapper?我目前的想法是只从shell脚本调用rake并让rake任务永远运行......提前致谢,克里斯。更新我们目前正在使用几个与Java线程相关的包装器,即https://github.com/jmettraux/rufus-scheduler和https://github.com/philostler/acts
在尝试实现应用auto_orient的过程之后!对于我的图片,我收到此错误:ArgumentError(noimagesinthisimagelist):app/uploaders/image_uploader.rb:36:in`fix_exif_rotation'app/controllers/posts_controller.rb:12:in`create'Carrierwave在没有进程的情况下工作正常,但在添加进程后尝试上传图像时抛出错误。流程如下:process:fix_exif_rotationdeffix_exif_rotationmanipulate!do|image|
我有一个将某些事件写入队列的Rails3应用。现在我想在服务器上创建一个服务,每x秒轮询一次队列,并按计划执行其他任务。除了创建ruby脚本并通过cron作业运行它之外,还有其他稳定的替代方案吗? 最佳答案 尽管启动基于Rails的持久任务是一种选择,但您可能希望查看更有序的系统,例如delayed_job或Starling管理您的工作量。我建议不要在cron中运行某些东西,因为启动整个Rails堆栈的开销可能很大。每隔几秒运行一次它是不切实际的,因为Rails上的启动时间通常为5-15秒,具体取决于您的硬件。不过,每天这样做几
已检查ActiveRecord、DataMapper、Sequel:有些使用全局变量(静态变量)有些需要在使用模型加载源文件之前打开数据库连接。在使用不同数据库的sinatra应用程序中使用哪种ORM更好。 最佳答案 DataMapper专为多数据库使用而设计。你可以通过像DataMapper.setup(:repository_one,"mysql://localhost/my_db_name")这样的方式设置多个存储库。DataMapper随后会跟踪所有已在哈希中设置的存储库,您可以引用该哈希并将其用于范围界定:DataMapp