【Linux进程篇】进程概念(1)

这篇具有很好参考价值的文章主要介绍了【Linux进程篇】进程概念(1)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【Linux进程篇】进程概念(1)

作者:爱写代码的刚子
时间:2023.7.30
前言:操作系统和软硬件的关系就相当于管理者和被管理者的关系,管理者并不需要见到被管理者,通过执行者拿到对应数据,通过对数据的管理来达到管理的目的。==对软硬件的管理最后一定会变成对某种数据结构的增删查改。==本篇博客将介绍操作系统如何对进程进行管理,如何创建进程。

进程

基本概念
  • 课本概念:程序的一个执行实例,正在执行的程序等

  • 内核观点:担当分配系统资源(CPU时间,内存)的实体。

    • 通俗一点:一个已经加载到内存中(运行)的程序叫做进程(任务),计算机在开机时也需要将操作系统从外设加载到内存中。
    • 一个操作系统,不仅仅只能运行一个进程,可以同时运行多个进程,所以操作系统必须将进程管理起来。
    • 进程需要先描述再进行管理
    • 任何一个进程,在加载到内存的时候,形成真正的进程时,操作系统要先创建描述进程的结构体对象(进程属性的集合)——PCB,process ctrl block——进程控制块
    • 进程属性: 进程编号、进程状态、优先级…
    • 操作系统根据进程的PCB,为该进程创建对应的PCB对象
    • 进程 = 内核PCB数据结构对象(描述你这个进程的所有属性值)[系统维护] + 你自己的代码和数据
    • 操作系统管理进程只需要管理PCB结构体对象
    • PCB中包含对应的指针信息找到代码和数据
    • 操作系统中中含有多个进程,对进程的管理变成了对双向链表进行增删查改
    • 所有操作系统都是按照以上方案来对进程进行管理(思路是一致),但是具体管理方法有差别。
    • 不要以为将程序加载到内存就叫进程,而是操作系统为了管理这个进程所创建的PCB结构体。(只写一份可执行程序,把同样的进程跑了两次,但是在系统层面上是两进程)
  • ps ajx查看所有进程
    【Linux进程篇】进程概念(1),Linux,linux,运维,服务器,进程,c++
    用vim编写一段代码,并执行:
    【Linux进程篇】进程概念(1),Linux,linux,运维,服务器,进程,c++

  • ps ajx | grep myprocess查看myprocess的进程状态

【Linux进程篇】进程概念(1),Linux,linux,运维,服务器,进程,c++

  • ps ajx | head -1 && ps ajx | grep myprocess将进程的属性也显示出来

【Linux进程篇】进程概念(1),Linux,linux,运维,服务器,进程,c++

描述进程-PCB
  • 进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。
  • 课本上称之为PCB(process control block),Linux操作系统下的PCB是: task_struct(PCB具体的一种)
task_struct-PCB的一种
  • 在Linux中描述进程的结构体叫做task_struct。
  • task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。
task_ struct内容分类
  • 标示符: 描述本进程的唯一标示符,用来区别其他进程。
  • 状态: 任务状态,退出代码,退出信号等。
  • 优先级: 相对于其他进程的优先级。
  • 程序计数器: 程序中即将被执行的下一条指令的地址。(CPU中有一个寄存器(程序计数器),当运行一个进程时,永远要把当时运行指令的下一条指令的地址记录下来,因为进程可能因为某些原因不被运行,唤醒时才运行
  • 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针(找到代码数据)
  • 上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
  • I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
  • 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
  • 其他信息
组织进程

可以在内核源代码里找到它。所有运行在系统里的进程都以task_struct链表的形式存在内核里。

Linux内核中,最基本的组织进程task_struct的方式是采用双向链表组织的,PCB还有其他的链式属性(队列、二叉树等,数据结构之间的关系非常错综复杂)

查看进程

进程的信息可以通过/proc系统文件夹查看

  • 如:要获取PID为1的进程信息,你需要查看/proc/1这个文件夹。

  • ls /proc查看当前系统的所有进程(关机之后目录里的数据没了,上面的所有信息是Linux操作系统用文件系统的方式把内存当中的文件包括进程信息给我们可视化出来,上面的数据都是内存级的)
    【Linux进程篇】进程概念(1),Linux,linux,运维,服务器,进程,c++
    运行指令时,所有的指令都变成了进程,这些指令都要加载到内存,以进程的方式去运行(很快)

【Linux进程篇】进程概念(1),Linux,linux,运维,服务器,进程,c++

  • ls /proc -l显示进程(蓝色数字是当前进程的PID)
    【Linux进程篇】进程概念(1),Linux,linux,运维,服务器,进程,c++
    【Linux进程篇】进程概念(1),Linux,linux,运维,服务器,进程,c++

当进程重新运行时PID很可能会变化
【Linux进程篇】进程概念(1),Linux,linux,运维,服务器,进程,c++
cwd:current work directory当前进程的工作目录(目录的重新理解

  • 大多数进程信息同样也可以使用top和ps这些用户级工具来获取
通过系统调用获取进程标示符

【Linux进程篇】进程概念(1),Linux,linux,运维,服务器,进程,c++

    • 进程id(PID)
    • 父进程id(PPID)
  • kill -9 +PID杀死对应进程

【Linux进程篇】进程概念(1),Linux,linux,运维,服务器,进程,c++

  • while :;do ps ajx | head -1 ; ps ajx | grep proc | grep -v grep;echo “--------------------------------------------”; sleep 1;done 打印进程相关的信息

【Linux进程篇】进程概念(1),Linux,linux,运维,服务器,进程,c++

  • getppid() 利用这个函数可以查看父进程id(头文件:#include <sys/types.h>)

  • 多次运行时父进程不会变,但是子进程会变
    【Linux进程篇】进程概念(1),Linux,linux,运维,服务器,进程,c++

  • 查看该程序的父进程(bash进程)
    【Linux进程篇】进程概念(1),Linux,linux,运维,服务器,进程,c++
    运行一个进程时,命令行解释器会将这个指令变成bash的子进程,由子进程执行对应的命令。

  • 每次登入iTerm时,系统会为我们单独创建一个bash进程(命令行解释的进程)(所有指令的父进程)

通过系统调用创建进程——fork初识
  • 运行man fork认识fork
  • fork有两个返回值
  • 父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝)

【Linux进程篇】进程概念(1),Linux,linux,运维,服务器,进程,c++

【Linux进程篇】进程概念(1),Linux,linux,运维,服务器,进程,c++

进程创建成功,给父进程返回子进程的PID,给子进程返回0;创建失败返回-1

  • 那是不是表示fork函数会返回两次?
    【Linux进程篇】进程概念(1),Linux,linux,运维,服务器,进程,c++

【Linux进程篇】进程概念(1),Linux,linux,运维,服务器,进程,c++
说明这个id具有两个值,说明fork()在程序运行期间创建了一个子进程。

【问题】:

    • 为什么能跑两份的代码?
      因为存在了两个进程。
    • 为什么fork要给子进程返回0,给父进程返回子进程PID?
      返回不同的返回值,是为了区分让不同的执行流,执行不同的代码块,一般而言fork之后的代码父子共享。给父进程返回子进程PID是为了标识子进程的唯一性,父进程来控制子进程,子进程只需调用getpid()就可以知道子进程的PID。
    • 一个函数是如何做到返回两次的?如何解释?
      fork()之后父子进程的代码是共享的,代码是不可以被修改的。虽然代码是共享的,但是我们是希望他们执行不同的代码块,这样才可能让父子进程协同起来。
      fork()也是一个函数,一个函数return了说明该函数的核心工作已经完成。
      fork()函数的功能可以总结为以下:
      1. 创建子进程PCB
      2. 填充PCB对应的内容
      3. 让子进程和父进程指向同样的代码
      4. 父子进程都是有独立的task_struct,可以被CPU调度运行
      5. … …
      6. return ret;

既然return ret;也是一份代码,说明父子进程共享这份代码,父进程在函数调度时返回一次,子进程在函数调度时返回一次。所以fork()函数返回了两次fork()return之前,子进程早就创建了

    • 一个变量怎么会有不同的内容?
      在任何平台,进程在运行的时候,是具有独立性的,直接决定了父子进程不能访问同一份数据,因为数据可能会被修改。(共享代码并不影响独立性),理论上子进程需要将父进程数据拷贝一份(操作系统实现)。但是子进程并不一定使用父进程的全部数据,如果全部拷贝父进程的数据可能造成资源的浪费,造成不必要的内存负担,所以子进程拷贝数据时会进行写时拷贝所以在进程刚创建的时候父子进程的代码和数据全都是共享的,但是一旦当子进程尝试去修改父进程的数据时,操作系统会重新开辟一块空间,去新开辟的这块空间进行写入。(用多少开多少空间)
      (深浅拷贝也用到了写实拷贝)
      由于fork()的返回值写入了id,子进程写入时发生了写实拷贝,操作系统对同一个id变量拷贝了两份,所以父子进程在使用id时,父子进程看到的id的内容就会不一样。(访问了不同的内存区)

【存疑】:同一个变量是如何让父子进程看到不同的内容?(地址空间章节里会介绍)

  • 如果父子进程被创建好,fork()往后谁先运行呢?
    谁先运行是不确定的,由调度器决定,调度的本质是对CPU资源的竞争,调度器的存在保证了竞争的公平

【问题】但是作者发现了一个问题:
【Linux进程篇】进程概念(1),Linux,linux,运维,服务器,进程,c++

按照上面的理解该程序的输出结果应该为:111111122222221111111
实际运行时:
【Linux进程篇】进程概念(1),Linux,linux,运维,服务器,进程,c++
【解释现象】:因为代码中的第一个printf打印的字符串后面没有加上\n,导致父进程打印完1111111,该字符串还存在缓冲区中,导致创建子进程时也将父进程的缓冲区也拷贝了,所以也将"1111111"打印了出来。


进程概念篇(1)结束文章来源地址https://www.toymoban.com/news/detail-621092.html

到了这里,关于【Linux进程篇】进程概念(1)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Linux运维】shell脚本检查服务器内存和CPU利用率

    在管理服务器时候写了一个 shell脚本,在服务上实现每天凌晨3点查系统的指定文件夹下的容量大小,如果超过10G就要删除3天前的内容,还要时刻查询内存和cpu利用率,如果超过80%就要提示用户出现过载 将以上代码保存为一个.sh文件,然后通过crontab在每天凌晨3点运行即可:

    2024年02月09日
    浏览(67)
  • Linux服务器中查看进程的四种方法

    1. 使用 ps aux 命令来查看,能以简单列表的形式显示出进程信息 ps aux 用于报告当前系统的进程状态。可以搭配kill指令随时中断、删除不必要的程序. ps 命令是最基本同时也是非常强大的进程查看命令,使用该命令可以确定有哪些进程正在运行和运行的状态、进程是否结束、进

    2024年02月02日
    浏览(42)
  • Linux网络编程:多进程 多线程_并发服务器

    文章目录: 一:wrap常用函数封装 wrap.h  wrap.c server.c封装实现 client.c封装实现 二:多进程process并发服务器 server.c服务器 实现思路 代码逻辑  client.c客户端 三:多线程thread并发服务器 server.c服务器 实现思路 代码逻辑  client.c客户端 ​​​​   read 函数的返回值 wrap.h  wrap

    2024年02月12日
    浏览(56)
  • Linux服务器常见运维性能测试(1)综合跑分unixbench、superbench

    最近需要测试一批服务器的相关硬件性能,以及在常规环境下的硬件运行稳定情况,需要持续拷机测试稳定性。所以找了一些测试用例。本次测试包括在服务器的高低温下性能记录及压力测试,高低电压下性能记录及压力测试,常规环境下CPU满载稳定运行的功率记录。 这个系

    2024年02月04日
    浏览(82)
  • Linux本地部署1Panel服务器运维管理面板并实现公网访问

    1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。高效管理,通过 Web 端轻松管理 Linux 服务器,包括主机监控、文件管理、数据库管理、容器管理等 下面我们介绍在Linux 本地安装1Panel 并结合cpolar 内网穿透工具实现远程访问1Panel 管理界面 执行如下命令一键安装 1Panel: 安

    2024年02月04日
    浏览(98)
  • 蓝易云:Linux系统sshd命令 – openssh服务器守护进程

    sshd是Linux系统中的一个守护进程,它提供了远程登录服务和安全的文件传输功能。以下是sshd的详细教程。 1. 安装openssh-server 在Debian/Ubuntu上安装openssh-server命令如下: sudo apt-get update sudo apt-get install openssh-server 在CentOS/RHEL上安装openssh-server命令如下: sudo yum update sudo yum install

    2024年02月16日
    浏览(49)
  • 基于linux下的高并发服务器开发(第二章)- 2.7 进程退出、孤儿进程、僵尸进程

    ◼ 父进程运行结束,但子进程还在运行(未运行结束),这样的子进程就称为孤儿进程 (Orphan Process)。 ◼ 每当出现一个孤儿进程的时候,内核就把孤儿进程的父进程设置为 init ,而 init 进程会循环地 wait() 它的已经退出的子进程。这样,当一个孤儿进程凄凉地结束 了其生

    2024年02月16日
    浏览(55)
  • Linux高并发服务器开发---笔记1(环境搭建、系统编程、多进程)

    0613 首先这整个系列笔记属于笔记①:牛客校招冲刺集训营—C++工程师中的 第四章 笔记。 视频课链接: 视频1:Linux高并发服务器开发(40h); 视频2:第4章 项目制作与技能提升(录播)(26h30min); 视频课3: 第5章 高频考点与真题精讲(录播)中的 5.10-5.13 项目回顾 有个学

    2024年02月15日
    浏览(67)
  • [1Panel]开源,现代化,新一代的 Linux 服务器运维管理面板

    本期测评试用一下1Panel这款面板。1Panel是国内飞致云旗下开源产品。整个界面简洁清爽,后端使用GO开发,前端使用VUE的Element-Plus作为UI框架,整个面板的管理都是基于docker的,想法很先进。官方还提供了视频的使用教程,本期为大家按照本专栏的基本内容进行多方面的测评。

    2024年02月07日
    浏览(94)
  • linux 服务器进程、端口查找,nginx 配置日志查找,lsof 命令详解

    1.1 使用查看端口号对应的进程信息 方式一 : 使用netstat命令 -t:显示TCP连接 -u:显示UDP连接 -l:仅显示监听状态的连接 -n:以数字形式显示端口号,而不是以服务名称显示 通过管道符号|将netstat的输出结果传递给grep命令,用于过滤出包含指定端口号的行。 执行命令后,终端

    2024年02月04日
    浏览(63)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包