-
【Linux】进程控制,手搓简洁版shell
1、进程创建 fork函数:从已经存在的进程中创建一个新进程。新进程为子进程,原进程为父进程。 进程调用fork,当控制转移到内核中的fork代码后,内核做: 分配新的内存块和内核数据结构给子进程 将父进程部分数据结构内容拷贝给子进程 添加子进程到系统进程列表当中 fork返回,开始调度器调度 写时拷贝 (懒拷贝,时间换空间) 数据在默认不修改的情况下是共享的,不各自拷贝一份是因为父子进程间的数据大部分是重复的,一般只有少量数据需要修改,因为各自拷贝一份浪费空间。 更新父进程页表项为只读—子进程继承—子进程写入—触发系统错误—系统触发缺页中断—系统检测—判定是否要写时拷贝—拷贝,修改,恢复权限。 创建出子进程,让子进程执行一些任务: #include <iostream> #include <vector> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <stdio.h> using namespace std; enum { OK, OPEN_FILE_ERROR }; vector<int> data; int savebegin() { string name = to_string((unsigned int)time(nullptr)); name += ".backup"; FILE *pf = fopen(name.c_str(), "w"); if (pf == nullptr) { return OPEN_FILE_ERROR; } string datastr; for (auto d : data) { datastr += to_string(d); datastr += " "; } fputs(datastr.c_str(), pf);//将拿到的数据备份到文件中 fclose(pf); return OK; } void save() { pid_t id = fork(); if (id == 0) { //子进程备份数据 int code = savebegin(); exit(code); } int status = 0; pid_t rid = waitpid(id, &status, 0); if (rid > 0) { int code = WEXITSTATUS(status);//进程退出码 if (code == 0) cout << "备份成功, exit code:" << code << endl; else cout << "……
SE_Wang 2024-12-023 0 0 -
Ubuntu20.04双系统安装详解(内容详细,一文通关!)
制作ubuntu系统安装盘 下载ubuntu镜像文件 这里给出两种下载方式: 1、官网下载 传送门🔗Download Ubuntu Desktop | Download | Ubuntu 如今官网上只能找到较新的ubuntu版本(截至到笔者写文时官网上显示的是Ubuntu 22.04.3 LTS和Ubuntu 23.04),较老的版本不太方便找到(反正笔者是真没找到呜呜呜)。【下载较新的ubuntu版本,容易导致在配置环境时有些插件不适配新版本的环境,产生诸多问题,所以不太推荐下载最新的版本】 2、清华大学开源软件镜像站(推荐!!) (1)传送门 🔗清华大学开源软件镜像站 | Tsinghua Open Source Mirror 搜索ubuntu-releases,点击20.04文件夹,即出现下图文件内容 选择文件“ubuntu-20.04.6-desktop-amd64.iso”,即可自动进行下载 (2)也可以直接点击下方文件链接进行下载 ubuntu-20.04.6-desktop-amd64.iso https://mirrors.tuna.tsinghua.edu.cn/ubuntu-releases/20.04/ubuntu-20.04.6-desktop-amd64.iso 制作ubuntu启动盘 首先需要准备一枚8GB以上的U盘,然后需要将上述下载的iso镜像文件写入U盘中 【注意,制作成启动盘后U盘内的所有内容都会被清除,所以请事先备份好其中所有的文件】 有关写入操作,在这里笔者使用的是win32diskImager工具 防止跑错网站,这里直接给出链接 传送门🔗Win32 Disk Imager download | SourceForge.net 点击Download即可 下载完成并打开后显示如下的界面: 在“映像文件”部分(红线表示)选择之前下载好的iso文件,“设备”部分(蓝线表示)选择将要制作成启动盘的U盘的盘符(在“我的电脑”界面会显示,一般是E、F、G等巴拉巴拉的,对应好就行),然后点击“写入”(绿色部分)。 【注意】如果搜索文件映像时找不到文件,可以点击右下角黄色涂抹区域更换一下文件类型,由“磁盘映像”文件类型更换为“*.*”文件类型,就可以显示iso文件咯~ 点击写入之后,……
SE_Wang 2024-11-29155 0 0 -
【Linux】文件操作的艺术——从基础到精通
前言:一切皆文件 在正式开始文件操作的介绍之前,我们先来解决一个问题,什么是文件? 我们常见的文件有:文本文件(如.txt,.cpp),二进制文件(如编译后的可执行文件),图像文件等等,我们和这些文件打交道,无非就是对文件写入和对文件读取,然而我们是怎么实现对文件的写入和读取的呢?其实操作系统为我们提供了这一切,我们告诉系统要访问哪个文件,调用系统提供的方法,就实现了对文件的操作。 但文件的概念并不仅仅局限于磁盘上的存储内容,在操作系统中,几乎所有资源都可以通过类似“文件”的方式来进行访问和操作。无论是硬盘上的数据,还是连接计算机的外设设备,操作系统都通过类似文件的机制来统一管理他们。这是操作系统设计的一个重要思想——一切皆文件。 在这个框架下,设备(如键盘、鼠标、网络接口、内存等)不再是与文件不同的资源,而是被抽象为一种特殊类型的文件,通过统一的系统调用接口,我们可以像操作普通文件那样,操作这些设备,这种设计方式使得我们能够以一种一致的方式访问硬件资源。 下面我们来介绍操作系统具体是如何对文件进行操作,以及如何以“文件”的方式管理各种设备的。 📚一、C语言的文件接口 任何对文件的操作都可以看成对数据的访问、读取和写入,系统为我们提供了这些操作的接口,下面我们就来看看C语言下的文件接口: 📖1.文件打开 🔖语法 C语言提供了标准库函数 fopen() 用于打开文件: FILE *fopen(const char *filename, const char *mode); ① 参数1:filename,表示文件名,指定要打开的文件路径,可以是绝对路径也可以是相对路径 ② 参数2:mode,文件打开模式,指定打开文件的方式(文件操作的权限),常见的有: "r",只读方式打开文件,文件必须存在 "w",只写方式打开文件,文件不存在则创建,存在则清空文件 "a",追加模式,文件不存在则创建,存在则数据追加……
SE_Wang 2024-11-2825 0 0 -
【Linux】权限管理
一.shell命令以及运行原理 Linux严格意义上说的是一个操作系统,我们称之为核心(kernel),但我们一般用户,不能直接使用kernel。而是通过kernel的"外壳"程序,也就是所谓的shell,来与kernel沟通。如何理解?为什么不能直接使用kernel? 从技术角度,Shell的最简单定义为命令行解释器主要包含: 将使用者的命令翻译给核心处理。 同时,将核心的处理结果翻译给使用者。 为什么要存在外壳程序? 用户不擅长直接与操作系统打交道,这是外壳程序的存在,使得用户操作更方便。 若用户进行了极其不合法的操作,外壳程序直接将该操作阻挡在外面,从而保护内核。 外壳程序以进程的方式呈现,当有新命令到来的时候,进程会创建子进程来执行新命令,子进程由于某种操作挂掉时,不会影响外壳程序。 对比windows GUI,我们操作windows 不是直接操作windows内核,而是通过图形接口,点击,从而完成我们的操作(比如进入D盘的操作,我们通常是双击D盘盘符或者运行起来一个应用程序) shell 对于Linux,有相同的作用,主要是对我们的指令进行解析,解析指令给Linux内核。反馈结果在通过内核运行出结果,通过shell解析给用户。 二.Linux权限管理 1.Linux中的用户 Linux含有两种用户 root用户:可以再linux系统下做任何事情,不受限制。 普通用户:权限低,受限制。 超级用户的命令提示符是"#“,普通用户的命令提示符是”$" 用户之间的身份切换:要从root用户切换到普通用户user,则使用 su user。 要从普通用户user切换到root用户则使用 su root(root可以省略),此时系统会提示输入root用户的密码。 2.sudo指令提权 sudo:用于指令的短暂提权(比如:安装软件到系统中,需要root管理员权限,其实只安装了一份,允许用户都可以使用) 3.权限 权限的本质:能或不能做什么事情。 权限控制用户的行为,防止错误的发生。 权限首先……
SE_Wang 2024-11-279 0 0 -
【Linux】「共享内存揭秘」:高效进程通信的终极指南
1. 什么是共享内存 共享内存(Shared Memory)是一种进程间通信(IPC,Inter-Process Communication)的方式,允许多个进程通过访问同一块内存区域来实现数据共享和快速通信。它是一种效率极高的通信机制,因为数据不需要在进程间进行复制,只需在同一块内存中直接读写即可。 1.2 共享内存的特点 高效:数据在高效内存区域是直接共享的,不需要在进程之间进行复制,从而减少了CPU和IO的消耗。 全局性:共享内存是所有附加到该内存的进程都可以访问的,由此它是一种全局资源。 同步机制依赖:虽然共享内存提供了数据共享的功能,但是不会自动提供对数据的访问同步机制。需要结合其他IPC方法(如信号量、互斥锁等)来避免多个进程同时读写时产生的数据竞争。 1.3 共享内存的工作原理 操作系统内核会在物理内存中分配一个共享内存段。 各个进程通过特定的标识符(shm_id)访问同一块共享内存空间。 共享内存区域是进程的地址空间外的内存,进程需要将其映射到自己的地址空间中才能访问。 还记得在进程地址空间时的内容吗? 共享内存的工作原理可以理解为:操作系统在内存中开辟了一块共享内存段,让两个不同的进程的虚拟地址同时对这块空间建立起映射关系,此时两个独立的进程能看到同一块空间,可以直接对此空间进行写入或者读取操作。 2.在Linux中使用共享内存 虽然Linux提供了POSIX和System V两种共享内存接口。但是本文将聚焦于System V 2.1 介绍System V System V(读作“System Five”)是 UNIX 操作系统家族的一个版本,由美国 AT&T 的贝尔实验室开发。它是早期 UNIX 的一个重要分支,并对后来的 UNIX 系统以及其他现代操作系统产生了深远影响。 虽然 System V 本身已经很少被直接使用,但它的思想和功能在现代操作系统中得到了传承。 比如:POSIX:吸收了 System V 的许多特性,成为跨平台的通用标准。 2……
SE_Wang 2024-11-2615 0 0 -
【Linux】进程的生命之旅——诞生、消逝与守候(fork/exit/wait)
一、进程创建 1.fork函数 操作系统中进程的创建通常是通过系统调用实现的,在Linux中是通过fork(),它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。 #include<unistd.h> // 使用需包含头文件unistd.h pid_t pid = fork(); // 在子进程中返回0,父进程中返回子进程pid,出错返回-1 fork是操作系统提供的一种高层封装,它抽象了进程创建的复杂过程,fork将底层的一系列操作封装在一个简单的系统调用中,屏蔽了许多复杂的细节: 📚高层封装特性 ① 简化进程创建的步骤: fork的调用接口非常简洁,只需要调用一次,系统会自动创建一个子进程并返回。父进程和子进程共享相同的代码,子进程可以继续从父进程的当前执行点运行。 ② 屏蔽底层细节: 底层需要分配新的内存空间、复制父进程的状态、初始化子进程的资源,fork函数将这些细节全部封装起来。 ③ 依赖操作系统: fork的具体实现以来于操作系统内核,它负责管理进程表等关键数据结构,系统调用fork,当控制转移到内核中的fork代码后,内核做: 1. 分配新的内存块和内核数据结构给子进程 2. 将父进程部分数据结构内容拷贝给子进程 3. 添加子进程到系统进程列表当中 4. fork返回,开始调度器调dan'ddandan 当一个进程调用fork之后就会有两个二进制代码相同的进程,并且都能运行到相同的地方,各自开始往下走: int main() { printf("Before: pid is %d, ppid is %d\n",getpid(),getppid()); fork(); printf("After: pid is %d, ppid is %d\n",getpid(),getppid()); return 0; } ❓这里为什么只有三行输出,子进程共享父进程的代码,并各自独立执行,应该是打印两次Before才对。分析打印结果,10226应该是父进程,确实打印了Before,而子进程10227没有打印Before,说明子进程并没有执行Before的代码,正如上面所说的,子进程继续从父进程的……
SE_Wang 2024-11-258 0 0 -
双向NAT=源NAT+NAT Server,有这么6?
01 NAT基础 网络地址转换(Network Address Translation, NAT)是一种用于重写IP数据包头部地址的技术,它允许一个或多个私有网络内的设备共享一个或多个全球唯一的IP地址来访问互联网。 NAT的引入主要是为了解决IPv4地址空间不足的问题,同时也增强了网络的安全性,因为内部网络的结构对外部观察者是隐藏的。 NAT的工作原理在于路由器或防火墙设备上运行的一个特殊程序。当来自私有网络的数据包离开本地网络时,NAT设备会将该数据包的源IP地址替换为一个全局可路由的IP地址。 相反地,当响应的数据包返回到私有网络时,NAT设备会将其目标IP地址恢复为原来的私有IP地址。 01NAT类型 静态NAT:为私有网络中的每个主机分配一个固定的公有IP地址。这种方式适用于需要持续公开访问的服务器。 动态NAT:从一组公有IP地址池中临时分配一个地址给私有网络中的主机。这种方式适用于不需要长期保持连接的主机。 端口地址转换(PAT):通过使用一个或少数几个公有IP地址,并结合不同的传输层端口号来区分不同的私有网络主机。PAT是目前最常用的NAT形式之一,因为它能够有效地利用有限的公有IP地址资源。 网络地址端口转换(NAPT):结合了NAT和PAT的特点,不仅转换IP地址,还转换端口号,从而支持大量的内部主机通过少量的外部IP地址进行通信。 02 源NAT 源NAT(Source NAT)是一种NAT技术,它的主要功能是在数据包离开私有网络进入公网时,修改数据包的源IP地址。 这样做的目的是为了让私有网络中的设备能够使用公共IP地址与外部网络通信。源NAT通常在边界路由器或防火墙上实现,以确保内部网络的私有IP地址不会暴露给外部网络。 01 工作流程: 内部主机发送数据包至边界路由器/防火墙。 边界设备检查数据包,并将源IP地址从私有地址转换成合法的公有IP地址。 数据包通过转换后的源IP地址被发送到外部网络。 当响应数……
SE_YJ 2024-11-258 0 0 -
SecureCRT这样设置,再也不背锅了!
01 SecureCRT简介 01功能概述 SecureCRT 是一款由 VanDyke Software 开发的远程终端仿真软件,它支持多种协议,包括 SSH(Secure Shell)、Telnet、Rlogin、Serial 和 TTY。 SecureCRT 以其出色的安全性和易用性著称,广泛应用于 IT 领域的专业人士,特别是那些需要频繁访问远程系统的运维工程师和技术支持人员。 02 SecureCRT 的主要功能特点: 安全连接:支持 SSH 协议,提供加密的远程登录方式,确保传输数据的安全性。 多会话支持:可以同时打开多个会话窗口,方便用户管理不同的远程连接。 日志记录:能够记录所有的会话活动,便于后续审计和问题追踪。 脚本支持:支持使用脚本语言(如 TCL/TK)来自动化复杂的任务。 自定义界面:用户可以根据个人喜好定制界面布局,提高工作效率。 多平台兼容:可在 Windows、macOS 和 Linux 等平台上运行。 03适用场景 SecureCRT 适用于多种场景,特别是在需要安全地管理和监控远程服务器的情况下: 服务器管理:通过 SSH 连接远程服务器,执行管理操作,如文件传输、命令执行等。 技术支持:为技术支持人员提供安全的远程访问手段,帮助他们更快地解决问题。 系统审计:记录用户的会话活动,便于进行系统审计和合规性检查。 开发测试:开发人员可以使用 SecureCRT 来测试和调试远程应用程序。 网络监控:网络管理员可以使用 SecureCRT 来监控和管理网络设备,如路由器、交换机等。 02 安装与配置 01安装步骤 下载安装包: 访问 VanDyke Software 的官方网站 (https://www.vandyke.com/) 下载 SecureCRT 的安装程序。 根据您的操作系统选择合适的版本(Windows、macOS 或 Linux)。 执行安装: 在 Windows 上,双击下载的安装程序,按照向导提示进行安装。 在 macOS 上,打开下载的 .dmg 文件,将 SecureCRT 拖拽到 Applications 文件夹中。 在 Linux 上,……
SE_YJ 2024-11-257 0 0 -
Linux 链式与层级中断控制器讲解:原理与驱动开发
1.处理流程对比 Linux 4.9.88内核源码 Linux-4.9.88\drivers\gpio\gpio-mxc.c📎gpio-mxc.c Linux-4.9.88\arch\arm\boot\dts\imx6ull.dtsi 1.1 下级中断控制器的类别 在后续课程中我们把GIC之下的中断控制器分为两类:链式(chained)、层级(hierarchy)。 (这个分类并没有官方定义) 1.1.1 链式中断控制器(chained) 上图中,左边的"chained intc"就是链式中断控制器。 它底下的4个中断触发时,都会导致GIC的33号中断被触发。 处理中断时,需要分辨:是谁触发了GIC 33号中断?这需要读取"chained intc"中的寄存器。 1.1.2 层级中断控制器(hierarchy) 上图中,右边边的"hierarchy intc"就是层级中断控制器。 它底下的4个中断,跟GIC中的4个中断一一对应。 处理GIC 100~103号中断时,不需要读取"hierarchy intc"的寄存器来分辨是谁触发了中断。 两种类型的中断控制器是可以组合的 1.2 链式中断控制器的处理流程 下图中: handleA、irq_dataA由GIC驱动提供 handleB、irq_dataB由GPIO驱动提供 handleC也是GPIO驱动提供 假设GPIO模块下有4个引脚,都可以产生中断,都连接到GIC的33号中断 GPIO就是一个链式中断控制器,它底下有4个中断 对于GPIO模块中0~3这四个hwirq,分配四个irq_desc 可以一下子分配4个:legacy,老方法 也可以用到时再分配:linear,新方法 假设这4个irq_desc的序号为100~103,在GPIO domain中记录(0,100) (1,101)(2,102) (3,103) 对于KEY,注册中断时就是:request_irq(102, ...) 按下KEY时: 程序从GIC中读取寄存器知道发生了33号中断,通过GIC irq_domain可以知道virq为17 处理virq 17号中断:调用irq_desc[17].handle_irq,即handleB mask/ack中断: 调用irq_desc[17].irq_data->irq_chip的函数,即irq_dataA 细分中断源、处理 读取GPIO寄存器,确定是GPIO里2号引脚发生中断 通过GPIO irq_doma……
SE_Wang 2024-11-2211 0 0 -
Linux :进程间通信之管道
一、进程间通信 1.1 是什么和为什么 1、进程间通信是什么?? ——>两个或多个进程实现数据层面的交互,但是由于进程独立性的存在,导致通信的成本比较高。 2、既然通信成本高,那为什么还要通信呢?? ——> 在某些场景下我们需要不同进程之间进行(1)基本数据的交互。(2)发送命令。(3)实现某种协同。(4)通知某些信息…… 1.2 如何实现进程间通信 1、进程间通信的本质:要想办法让不同的进程看到同一份资源(以特定形式存在的内存空间)! 2、这个资源必须由操作系统提供!! 问题: 为什么必须由操作系统提供呢??难道不能由其中一个进程提供么?? ——>假设由一个进程提供,而我们又让另一个进程看到这份资源,那么这份资源应该属于谁呢?? ——>所以这种做法会破坏进程的独立性!!所以我们必须需要第三方空间,因此只能由操作系统提供! 举个例子:保持进程独立性,可以理解为就是我俩不能见面,就好比说一个绑匪把你绑架了,但是他并不会直接去你家取赎金,也不会让你家人把赎金送到自己的住所,而是会要求你的家人把钱放到一个地方,然后你再去取。 3、我们进程访问这个空间,本质上就是在访问操作系统!! ——>因为进程代表的就是用户,而操作系统并不相信用户,所以“资源”从创建、使用再到释放,必须使用系统调用接口!! 4、一般操作系统,会有一个独立的通信模块——隶属于文件系统——IPC通信模块 其中有两套标准 system V && posix 5、基于文件级别的通信方式——管道 1.3 进程间通信的方案设计 进程是具有独立性的,但是早期有的人发现我们很多时候需要通信,比如果进程需要通信,网络也需要通信,所以大家发现通信很重要,另一方面由于通信模块的设计相对简单,且可实现方案多样化,因此大家你做你的,我做我的,导致现在很多Linux发型版本都不一样,即使一样,内部的标准也不一……
SE_Wang 2024-11-2117 0 0