【Linux】12.Linux进程概念(1)

文章目录

  • 1. 冯诺依曼体系结构
  • 2. 操作系统(Operator System)
    • 概念
    • 设计OS的目的
    • 胆小的操作系统
    • 定位
    • 如何理解 "管理"
    • 总结
  • 3. 进程
    • 基本概念
    • task_struct-PCB的一种
    • task_ struct内容分类
    • 组织进程
    • 查看进程
    • 通过系统调用获取进程标示符
    • 通过系统调用创建进程-fork初识


1. 冯诺依曼体系结构

我们常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系。

9cb69cb2cf28cc8c5126f82f9cba886f

截至目前,我们所认识的计算机,都是有一个个的硬件组件组成

  • 输入单元:包括键盘, 鼠标,扫描仪, 写板等

  • 中央处理器(CPU):含有运算器和控制器等

  • 输出单元:显示器,打印机等

关于冯诺依曼,必须强调几点:

  • 这里的存储器指的是内存

  • 不考虑缓存情况,这里的CPU能且只能对内存进行读写,不能访问外设(输入或输出设备)

  • 外设(输入或输出设备)要输入或者输出数据,也只能写入内存或者从内存中读取。

  • 一句话,所有设备都只能直接和内存打交道

  1. 存储器:内存

  2. 输入设备:鼠标,键盘,摄像头,话筒,磁盘,网卡…

  3. 输出设备:显示器,播放器硬件,磁盘,网卡…

有的设备是纯输入输出,也有的又是输入又是输出。

输入设备和输出设备统称为外设。

  1. 运算器:对我们的数据进行计算任务(算数运算,逻辑运算)
  2. 控制器:对我们的计算硬件流程进行一定的控制。

运算器和控制器统称为CPU

上面这些东西都是独立的个体,所以要用总线连接起来。

总线分为系统总线和IO总线。

存储是有效率的。寄存器最快,缓存其次,内存其次,外存最慢。


2. 操作系统(Operator System)

概念

任何计算机系统都包含一个基本的程序集合,称为操作系统(OS)。笼统的理解,操作系统包括:

  • 内核(进程管理,内存管理,文件管理,驱动管理)

  • 其他程序(例如函数库,shell程序等等)


设计OS的目的

与硬件交互,管理所有的软硬件资源(手段)

为用户程序(应用程序)提供一个良好的执行环境(目的)


胆小的操作系统

操作系统里面会有各种的数据,可是操作系统不信任任何用户。

操作系统为了保证自己数据安全,也为了保证给用户能够提供服务,操作系统以接口的方式给用户提供调用的入口,来获取操作系统内部的数据。

接口是操作系统提供的,用C实现的,自己内部的函数调用(系统调用)

所有访问操作系统的行为,都只能通过系统调用实现。


定位

在整个计算机软硬件架构中,操作系统的定位是:一款纯正的“搞管理”的软件


如何理解 “管理”

管理的例子

描述被管理对象

组织被管理对象

a0d5390015d6b4219fdd963933684250

操作系统可以认为是决策者,驱动程序可以认为是执行者,软硬件资源可以认为是被管理者。

先描述,再组织

在操作系统中,管理任何对象,最终都可以转化为对某种数据结构的增删查改。

C/C++的库函数和系统调用之间的关系就是上下层的调用和被调用的关系。


总结

计算机管理硬件

  1. 描述起来,用struct结构体
  2. 组织起来,用链表或其他高效的数据结构

3. 进程

基本概念

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

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

描述进程-PCB

进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。

课本上称之为PCB(process control block),Linux操作系统下的PCB是: task_struct

一个操作系统,不仅仅只能运行一个进程,还可以同时运行多个进程。

操作系统必须严格讲进程管理起来。

任何一个进程在加载到内存的时候,形成真正的进程时,操作系统要先创建描述进程属性的结构体对象PCB – 进程控制块。

可以认为PCB就是进程属性的集合,strut结构体里面存放的是进程编号,进程的状态,优先级…

进程 = 内核PCB的数据结构对象(描述你这个进程的所有的属性值) + 你自己的代码和数据


task_struct-PCB的一种

  • 在Linux中描述进程的结构体叫做task_struct。

  • task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。


task_ struct内容分类

  • 标示符: 描述本进程的唯一标示符,用来区别其他进程。

  • 状态: 任务状态,退出代码,退出信号等。

  • 优先级: 相对于其他进程的优先级。

  • 程序计数器: 程序中即将被执行的下一条指令的地址。

  • 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针

  • 上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。

  • I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。

  • 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。

  • 其他信息


组织进程

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

在操作系统中,对进程进行管理,可以抽象为对一个个PCB连接起来的一个单链表的增删改查。

pcb -> task_struct结构体,里面包含进程的所有属性。

Linux中树如何组织进程,Linux内核中,最基本的组织进程task_struct的方式,采用双向链表组织的。


查看进程

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

80fa53e2a692d0343cdebdae3c103e66

48f2ad6f3d639ca09b011cce8876fe06

简单写一个简单程序

6a96d659a2dbd4e07b36becc834dc939

我这里把这个进程杀掉,那个进程就自动死掉了。(这里的进程号和上面不同是因为我中间关掉了程序一次)

c7fa94819b0f36e48b0ade826b94dd80


通过系统调用获取进程标示符

  • 进程id(PID)

  • 父进程id(PPID)

proc.c

#include <stdio.h>
#include <unistd.h>

int main(){
        while(1)
        {
                printf("I am a process,my id is:%d\n",getpid());
                sleep(1);
        }
        return 0;
}

输入:

while : ; do ps ajx | head -1 ; ps ajx |grep proc |grep -v grep;echo"----------------------";sleep 1;done
# while : ; do ... done
# 创建一个无限循环
# : 是一个始终返回true的命令
# 会一直循环执行直到你按 Ctrl+C 停止

# ps ajx | head -1                    # 显示进程列表的表头
# ps ajx | grep proc | grep -v grep   # 查找名为"proc"的进程(排除grep进程本身)
# echo "----------------------"        # 打印分隔行
# sleep 1                             # 暂停1秒

一开始没有运行程序,后来开启了进程。

833cf1c3283d242ac3fa42c892efa53d

然后改一下proc.c的代码

#include <stdio.h>
#include <unistd.h>

int main(){
        while(1)
        {
                printf("I am a process,my id is:%d,parent:%d\n",getpid(),getppid());
                sleep(1);
        }
        return 0;
}

里面的父进程和子进程的id也能对的上。

41fb3a0c665e4687de4e4c7e81ee89bc

这里每次子进程的pid都在变,但是父进程的ppid却不变。

aa534260085dda54a084529fe2d47e02

这个父进程是谁呢?

原来是bash

e5c791bd2dafe173ba677c373e94249e

这个bash在我们每次登录系统的时候,系统会默认分配一个bash进程给我们。


通过系统调用创建进程-fork初识

  • 运行 man fork 认识fork

  • fork有两个返回值

  • 父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝)

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main()
{
    printf("我是一个进程,pid:%d, ppid:%d\n",getpid(),getppid());
    pid_t id=fork();
    if(id==0){
        //子进程
        while(1){
            printf("我是子进程,pid:%d, ppid:%d\n",getpid(),getppid());
            sleep(1);
        }
    }
    else if(id>0){
        //父进程
        while(1){
            printf("我是父进程,pid:%d, ppid:%d\n",getpid(),getppid());
            sleep(1);
        }
    }
    else{
        //error
    }
    return 0;
}

这里面出现了我是子进程我是父进程,说明fork返回了两个值,简直是匪夷所思啊,以前的函数明明只能返回一个值的。

这里说明,fork又创建了一个进程,并且出现了父进程和子进程的死循环。

一开始这个程序是只有一个进程的,后来多出来一个子进程,形成了一个分支。

29a9c8c448252ed53e3c1a91dfa8564a

  1. 为什么fork要返回两个值?给父进程返回子进程的pid,给子进程返回0呢?

    返回不同的返回值,是为了区分,让不同的执行流,执行不同的代码块。

  2. 一个函数是如何做到返回两次的?如何理解?

    fork也是个函数,当一个函数到了return语句的时候,他应该执行的核心工作已经实现完了。

    return语句也是代码,是被父子进程所共享的,所以父进程的return执行好了 会执行子进程的return

  1. fork函数究竟在干什么?干了什么?

进程=内核数据结构+代码和数据

一开始只有一个进程,也就是父进程,他有它对应的数据和代码。

然后新创建了一个子进程,子进程刚被创建出来的时候,是没有对应的代码和数据的,所以会指向父进程对应的代码。

所以fork之后,父子进程的代码是共享的。

f1ef3f05f01b96d50d2d229951835562

但我们创建子进程肯定是想让子进程完成和父进程不一样的事情,所以我们要想办法让父和子进程执行不同的代码块。

这就让fork有了不同的返回值。

  1. 一个变量为什么会有不同的内容?如何理解?

在任何平台,进程在运行的时候,是具有独立性的。我一个进程崩了不会影响其他的进程。

上面讲到,子进程会和父进程共用代码块,但是子进程没有数据,只能也死皮赖脸的从父进程拷贝一个数据,这个操作是操作系统自动完成的。

于是,两个进程的数据独立,代码公共,自然可以返回两个不同的内容了。

当然上面只是我们期望的,实际上子进程直接拷贝父进程的数据会导致数据太冗余了。

所以操作系统在子进程要对父进程的数据进行修改的时候,要改哪段,就会申请哪段的数据,可以称为数据层面的写时拷贝。

当子进程不修改父进程数据时,会采用写时父进程的数据和代码。

b75b3d4eed4f364034b0e1c0e38c2695

  1. 父子进程创建好后,fork先运行父进程还是子进程?

    不确定,谁先运行由调度器确定。

    调度器:选择运行哪个进程。(尽可能地平均和公平)

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

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

相关文章

LabVIEW 程序中的 R6025 错误

R6025错误 通常是 运行时库 错误&#xff0c;特别是与 C 运行时库 相关。这种错误通常会在程序运行时出现&#xff0c;尤其是在使用 C 编译的程序或依赖 C 运行时库的程序时。 ​ 可能的原因&#xff1a; 内存访问冲突&#xff1a; R6025 错误通常是由于程序在运行时访问无效内…

03JavaWeb——Ajax-Vue-Element(项目实战)

1 Ajax 1.1 Ajax介绍 1.1.1 Ajax概述 我们前端页面中的数据&#xff0c;如下图所示的表格中的学生信息&#xff0c;应该来自于后台&#xff0c;那么我们的后台和前端是互不影响的2个程序&#xff0c;那么我们前端应该如何从后台获取数据呢&#xff1f;因为是2个程序&#xf…

2024 京东零售技术年度总结

每一次回望&#xff0c;都为了更好地前行。 2024 年&#xff0c;京东零售技术在全面助力业务发展的同时&#xff0c;在大模型应用、智能供应链、端技术、XR 体验等多个方向深入探索。京东 APP 完成阶段性重要改版&#xff0c;打造“又好又便宜”的优质体验&#xff1b;国补专区…

Apache搭建https服务器

Apache搭建https服务器 REF: 使用OpenSSL自建一个HTTPS服务

XML在线格式化 - 加菲工具

XML在线格式化 打开网站 加菲工具 选择“XML 在线格式化” 输入XML&#xff0c;点击左上角的“格式化”按钮 得到格式化后的结果

BO-SVM贝叶斯算法优化支持向量机的数据多变量时间序列预测

BO-SVM贝叶斯算法优化支持向量机的数据多变量时间序列预测 目录 BO-SVM贝叶斯算法优化支持向量机的数据多变量时间序列预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab基于BO-SVR贝叶斯算法优化支持向量机的数据多变量时间序列预测&#xff0c;加入5折交叉验…

flutter R库对图片资源进行自动管理

项目中对资源的使用是开发过程中再常见不过的一环。 一般我们在将资源导入到项目中后,会通过资源名称来访问。 但在很多情况下由于我们疏忽输入错了资源名称,从而导致资源无法访问。 所以,急需解决两个问题: 资源编译期可检查可方便预览资源安装相关插件 在vscode中安装两…

【鱼皮大佬API开放平台项目】Spring Cloud Gateway HTTPS 配置问题解决方案总结

问题背景 项目架构为前后端分离的微服务架构&#xff1a; 前端部署在 8000 端口API 网关部署在 9000 端口后端服务包括&#xff1a; api-backend (9001端口)api-interface (9002端口) 初始状态&#xff1a; 前端已配置 HTTPS&#xff08;端口 8000&#xff09;后端服务未配…

Windows远程桌面网关出现重大漏洞

微软披露了其Windows远程桌面网关&#xff08;RD Gateway&#xff09;中的一个重大漏洞&#xff0c;该漏洞可能允许攻击者利用竞争条件&#xff0c;导致拒绝服务&#xff08;DoS&#xff09;攻击。该漏洞被标识为CVE-2025-21225&#xff0c;已在2025年1月的补丁星期二更新中得到…

‌如何有效学习PyTorch:从基础到实践的全面指南‌

随着人工智能和深度学习技术的飞速发展&#xff0c;PyTorch作为当前最流行的深度学习框架之一&#xff0c;凭借其动态计算图、灵活的编程模型以及强大的社区支持&#xff0c;在学术界和工业界均得到了广泛应用。本文旨在为初学者和有一定基础的读者提供一套系统、全面的PyTorch…

2Spark Core

2Spark Core 1.RDD 详解1) 为什么要有 RDD?2) RDD 是什么?3) RDD 主要属性 2.RDD-API1) RDD 的创建方式2) RDD 的算子分类3) Transformation 转换算子4) Action 动作算子 3. RDD 的持久化/缓存4. RDD 容错机制 Checkpoint5. RDD 依赖关系1) 宽窄依赖2) 为什么要设计宽窄依赖 …

视频超分(VSR)论文阅读记录/idea积累(一)

STAR: Spatial-Temporal Augmentation with Text-to-Video Models for Real-World Video Super-Resolution 关键词: text-to-video (T2V) Local Information Enhancement Module (LIEM) Dynamic Frequency (DF) 引言: VSR: 传统VSR分两大类recurrent-based和sliding-wind…

MySQL8数据库全攻略:版本特性、下载、安装、卸载与管理工具详解

大家好&#xff0c;我是袁庭新。 MySQL作为企业项目中的主流数据库&#xff0c;其5.x和8.x版本尤为常用。本文将详细介绍MySQL 8.x的特性、下载、安装、服务管理、卸载及管理工具&#xff0c;旨在帮助用户更好地掌握和使用MySQL数据库。 1.MySQL版本及下载 企业项目中使用的…

Docker安装PostGreSQL docker安装PostGreSQL 完整详细教程

Docker安装PostGreSQL docker安装PostGreSQL 完整详细教程 Docker常用命令大全Docker 运行命令生成Docker 上安装 PostGreSQL 14.15 的步骤&#xff1a;1、拉取 PostGreSQL 14.15 镜像2、创建并运行容器3、测试连接4、设置所有IP都可以运行连接进入容器内 修改配置文件关闭容器…

Elasticsearch:Jira 连接器教程第一部分

作者&#xff1a;来自 Elastic Gustavo Llermaly 将我们的 Jira 内容索引到 Elaasticsearch 中以创建统一的数据源并使用文档级别安全性进行搜索。 在本文中&#xff0c;我们将回顾 Elastic Jira 原生连接器的一个用例。我们将使用一个模拟项目&#xff0c;其中一家银行正在开发…

Spring 6 第1章——概述

一.Spring是什么 Spring是一款主流的Java EE轻量级&#xff08;体积小、不需要依赖其它组件&#xff09;开源框架Spring的目的是用于简化Java企业级应用的开发难度和开发周期Spring的用途不仅限于服务端的开发&#xff0c;从简单性、可测试性和松耦合的角度而言&#xff0c;任…

git管理源码之git安装和使用

git是什么&#xff1f; git是一个开源的分布式版本控制系统&#xff0c;可以有效、高速地处理从很小到非常大的项目版本管理&#xff0c;也是Linus Torvalds为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件。git与常用的版本控制工具SVN等不同&#xff0c;它采用…

大疆最新款无人机发布,可照亮百米之外目标

近日&#xff0c;DJI 大疆发布全新小型智能多光旗舰 DJI Matrice 4 系列&#xff0c;包含 Matrice 4T 和 Matrice 4E 两款机型。DJI Matrice 4E 价格为27888 元起&#xff0c;DJI Matrice 4T价格为38888元起。 图片来源&#xff1a;大疆官网 DJI Matrice 4E DJI Matrice 4T D…

基于Java的语音陪聊软件——支持聊天私聊-礼物系统-直播系统-缘分匹配-游戏陪玩

丰富的经验、成熟的技术&#xff0c;打造适合当下市场发展的语音交友软件源码。Java 语言凭借其独特的优势&#xff0c;为这款语音陪聊软件的稳健运行和持续发展奠定了坚实基础。它不仅融合了聊天私聊、礼物系统和直播系统等实用且有趣的功能&#xff0c;还创新性地引入了缘分匹…

npm发布工具包+使用

1.初始化package包 npm init -y {"name": "common-cjs-tools","version": "1.0.0","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" &&…