草庐IT

Linux——进程

Code_uu 2024-01-08 原文

进程介绍及其使用

1、认识冯诺依曼体系

在计算机的硬件结构中,有着图灵和冯诺依曼俩位举足轻重的人物。对于计算机的发展来说有着十分重要的意义。冯诺依曼结构也是现在大多数计算机的硬件结构。
输入、输出设备都是外设。外设数据传输时比较慢,例如磁盘相较于内存来说速度就比较慢。为了防止木桶效应。计算机为了兼顾这些外设运行速度就不得不说到存储器,这里的存储器就是特指内存。因为CPU计算速度十分快,所以内存可以帮我们对于数据进行预加载。这样CPU进行数据访问时就不需要访问外设,直接在内存中就可以的得到数据。所以在数据层面上一般CPU不会直接和外设沟通,而是直接和内存打交道。与外设进行数据层面沟通一般是内存。

在硬件层面上,单机和跨主机之间数据流向是通过一台冯诺依曼体系结构的输入设备输入进入内存,内存被CPU访问后。通过控制器进行数据输出到内存,再由内存输出到输出设备。中间还有一些其他设备在中间进行传输到另外一台冯诺依曼体系。进行相同方法数据的读取及其访问。

2、操作系统

任何计算机系统都包含一个基本的程序集合,称为操作系统(OS)。笼统的理解,操作系统包括:内核(进程管理,内存管理,文件管理,驱动管理)其他程序(例如函数库,shell程序等等)

本质就是一款对于软硬件资源管理的软件。

如何理解操作系统对硬件做管理?

在理解上软件、硬件本就是不同概念。所以比较形象理解就是领导对于公司给出决策。策划对于决策执行,员工实现策划给出的方案。实施后数据好坏都会被统计,反馈。但是对于整个方案实施。领导只是给了决策对于方案实施并没有参与,但是通过数据分析后就可以对于公司作出管理。对于满勤员工进行奖金发放,缺勤的员工进行惩罚。并没有直接和员工进行面对面交流沟通。只是通过保安对于每天员工打卡数据的进行一个管理。就可以实现公司管理。每一个员工在公司中的职位、工资,名字……进行一个结构体或者类的定义,这样就方便管理。所以管理就是建模,是对于管理对象数据的管理。

管理本质:先描述,在组织

在操作系统软件中就是通过计算机语言描述,用单链表或者更加高效的数据结构来进行组织管理。

3、进程

程序的一个执行实例,正在执行的程序等。内核观点:担当分配系统资源(CPU时间,内存)的实体。在操作系统中就是PCB,linux中是task_struct。

平时使用应用和运行一个可执行程序就会有得到一个进程。可以在我们电脑的任务管理器中查看自己当前运行的进程。当我们关闭一个应用时是不会影响我们其他应用的。所以进程是独立的。不会相互影响。在linux中也可以使用命令

ps axj

对于当前用户还可以使用命令

top -u 用户名//查看当前运行任务

对于每一个进程操作系统要进行管理,毕竟内存空间是有限的。冯诺依曼体系就决定了进程使用就需要用内存进行数据预加载。将文件的内容加载内存,不同进程管理就需要不同的pcb进行进程管理。对于pcb中会保存进程的基本属性。linux中task_struct属性基本就是

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

如何创建进程

在程序中使用fork函数。函数返回值

子进程返回0;父进程会返回子进程的pid。返回-1就是创建失败。

函数执行数据代码可以是共享的,也可以在不同进程中对数据,因为使用函数后对于产生不同的输出流。对于数据会发生写时拷贝

会对不同属性进程的优先级作出判断方便进程调度。在linux下可以验证进程独立

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

    pid_t ret=fork();
    
    if(ret==0)
    {
        while(1)
        {
            printf("这是子进程,我的pid:%d,父进程ppid:%d\n",getpid(),getppid());

        }
    sleep(1);
    }
  
  else if(ret>0)
  {
    
        while(1)
        {
            printf("这是父进程,我的pid:%d,父进程ppid:%d\n",getpid(),getppid());

        }
        sleep(1);
  }
    return 0;
}


然后进行对于一个进程使用kill命令

进程的pid每一次运行是不同,根据os的每次调用来进行分配。也可以理解是对于同一所学校报考后。入学会产生一个学号。但是一旦休学后在进入学校学习后有新的学号。可以通过进程的pid来识别不同进程。os对于内存进行管理也会在进程较多时,接近于宕机时对于部分进程进行kill命令来减缓内存压力。

进程状态

首先是阻塞状态,还有挂起状态。

阻塞:进程因为等待某些条件就绪,而导致的一种不推进状态。

对于常见进程阻塞就是在启动多个应用时,造成的系统卡顿。就是多个应用启动时都会使用同一份资源比如说是网卡,对于多个应用同时需要向外界发送信息时。资源就比较紧缺。CPU就会对于进程的先后顺序进行排队使用。等前面使用完资源后,资源再被自己使用。但是当CPU要处理单机的进程时,对于还没有得到资源的进程就会处于挂起状态。挂起后的进程代码和数据被放置在磁盘中的,内存中只有进程的pcb,当CPU再次调度该进程时,数据和代码才会被预加载进入内存。
常见状态

R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。
S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠(interruptible sleep))
D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的
进程通常会等待IO的结束。
T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可
以通过发送 SIGCONT 信号让进程继续运行。


对于上面代码运行后后发现状态不是R状态,而是S状态。这是因为CPU运行速度大于外设运行速度。通过printf函数向显示器打印数据。所以在CPU看来就是大多时候是在进程挂起状态。还有状态后面有一个‘+’。这是用于区分状态在前台运行还是在后台运行的标志。可以使用

kill -19 进程pid//暂停进程
kill -18 进程pid//恢复进程


再次恢复后,'+'消失。但是再次使用Ctrl+c就会发现无法终止进程,只能终止前台运行的进程。需要kill -9命令来终止进程(后台、前台进程都可以终止)。D状态暂时没有遇见过,但是对于系统的危害极大,会造成内存泄漏。可以直接断电终止该状态。但是数据会丢失。还有就是等待它自己恢复。

有关Linux——进程的更多相关文章

  1. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在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',

  2. ruby - 通过 ruby​​ 进程共享变量 - 2

    我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

  3. ruby - 无法在 Ruby 中将 ffmpeg 作为子进程运行 - 2

    我正在尝试使用以下代码通过将ffmpeg实用程序作为子进程运行并获取其输出并解析它来确定视频分辨率:IO.popen'ffmpeg-i'+path_to_filedo|ffmpegIO|#myparsegoeshereend...但是ffmpeg输出仍然连接到标准输出并且ffmepgIO.readlines是空的。ffmpeg实用程序是否需要一些特殊处理?或者还有其他方法可以获得ffmpeg输出吗?我在WinXP和FedoraLinux下测试了这段代码-结果是一样的。 最佳答案 要跟进mouviciel的评论,您需要使用类似pope

  4. Ruby 守护进程导致 ActiveRecord 记录器 IOError - 2

    我目前正在用Ruby编写一个项目,它使用ActiveRecordgem进行数据库交互,我正在尝试使用ActiveRecord::Base.logger记录所有数据库事件具有以下代码的属性ActiveRecord::Base.logger=Logger.new(File.open('logs/database.log','a'))这适用于迁移等(出于某种原因似乎需要启用日志记录,因为它在禁用时会出现NilClass错误)但是当我尝试运行包含调用ActiveRecord对象的线程守护程序的项目时脚本失败并出现以下错误/System/Library/Frameworks/Ruby.frame

  5. ruby - 在 ruby​​ 中生成一个进程,捕获 stdout,stderr,获取退出状态 - 2

    我想从ruby​​rake脚本运行一个可执行文件,比如foo.exe我希望将foo.exe的STDOUT和STDERR输出直接写入我正在运行rake任务的控制台.当进程完成时,我想将退出代码捕获到一个变量中。我如何实现这一目标?我一直在玩backticks、process.spawn、system但我无法获得我想要的所有行为,只有部分更新:我在Windows上,在标准命令提示符下,而不是cygwin 最佳答案 system获取您想要的STDOUT行为。它还返回true作为零退出代码,这可能很有用。$?填充了有关最后一次system调

  6. ruby-on-rails - 如何用不同的用户运行nginx主进程 - 2

    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的端口(因为绑定(

  7. Ruby 守护进程和 JRuby - 备选方案 - 2

    我有一个应用程序正在从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

  8. ruby-on-rails - Rails - Carrierwave 进程抛出 ArgumentError : no images in this image list - 2

    在尝试实现应用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|

  9. ruby-on-rails - Ruby 长时间运行的进程对队列事件使用react - 2

    我有一个将某些事件写入队列的Rails3应用。现在我想在服务器上创建一个服务,每x秒轮询一次队列,并按计划执行其他任务。除了创建ruby​​脚本并通过cron作业运行它之外,还有其他稳定的替代方案吗? 最佳答案 尽管启动基于Rails的持久任务是一种选择,但您可能希望查看更有序的系统,例如delayed_job或Starling管理您的工作量。我建议不要在cron中运行某些东西,因为启动整个Rails堆栈的开销可能很大。每隔几秒运行一次它是不切实际的,因为Rails上的启动时间通常为5-15秒,具体取决于您的硬件。不过,每天这样做几

  10. ruby - 在一个进程多个数据库连接 sinatra 应用程序中使用什么 ORM? - 2

    已检查ActiveRecord、DataMapper、Sequel:有些使用全局变量(静态变量)有些需要在使用模型加载源文件之前打开数据库连接。在使用不同数据库的sinatra应用程序中使用哪种ORM更好。 最佳答案 DataMapper专为多数据库使用而设计。你可以通过像DataMapper.setup(:repository_one,"mysql://localhost/my_db_name")这样的方式设置多个存储库。DataMapper随后会跟踪所有已在哈希中设置的存储库,您可以引用该哈希并将其用于范围界定:DataMapp

随机推荐