初识Linux · 进程(3)
目录
前言:
进程的创建
前言:
继上文介绍了着重介绍了进程的内部属性,以及在操作系统层面进程如何被组织起来的,如何调用系统接口,有关task_struct,进程的部分理解等,今天,我们就从进程的相关属性入手,
进程的创建
承接上文。
上文介绍了进程的创建方式是调用系统接口fork,所以有的时候,对子进程理解不深的人会写出如下代码:
while(1)
{printf("aaa\n");fork();printf("...\n");
}
代码本身是没有什么错误的,但是打印出来的时候,会发现打印出来并不是一个父进程一个子进程的打印,因为子进程会执行父进程后面的代码,所以也会执行这个死循环,从而导致子进程创建子进程,变成了指数级别的增长,所以打印第二个printf是1 2 4 8 的打印,容易让人摸不着头脑。
下一个场景,我们写了如下代码:
printf("I am a child process,my pid is %d\n",getpid());
printf("I am a parent process,my pid is %d\n",getppid());

当我们不管怎么运行,发现pid是会改变的,这很正常,但是为什么ppid是不变的呢?这是正常的吗?
当我们使用指令ps -xaj打开了任务管理器的界面,我们就会发现2878的进程是bash(不一定2878就是bash,也可能会有变化,参照./test,每个进程的pid都是会变化的)

那么什么是bash呢?
当我们运行:

就会有bash提示你说,./是个目录,无法运行。
其实bash就是命令行解释器,我们刚才运行的./test就像是一个公司的实习生而已,它呢,实际上就是公司的boss,掌管所有的实习生(子进程)。
提问,我们为什么创建子进程呢?
根据前面的代码我们知道,子进程会继承父进程后面的所有代码,但是我们创建子进程就是为了执行后面的代码吗?父进程也可以执行啊,为什么要创建呢?这时候,前面埋下的伏笔就起作用了,这里有个很让人迷惑的问题,一个函数的返回值可以返回几次呢?
欸大多数初学者可能都会回答一次,但是fork的奇异之处就在这里:

当我们man fork之后,在手册里面查询返回值的时候,返回值的描述是这样的:
On success, the PID of the child process is returned in the parent, and 0 is returned in the child. On failure, -1 is returned in the parent, no child process is created, and errno is ...
翻译过来就是,成功创建子进程,那么子进程的Pid就会返回给父进程,0返回给子进程,失败了就是返回-1给父进程,也就是说,成功了会有两个返回值,我们就可以写如下代码:
7 pid_t id = fork();8 if(id == 0)9 {10 printf("hehehe\n");11 }12 else 13 {14 printf("hahahha\n");15 }16
最后的打印结果是:

按照以前C语言的逻辑,是只会打印一个的,这里就有点颠覆了代码三观了~
但是奇怪了,明明变量只有一个id啊,为什么会有两份?
实际上在fork的时候,fork的实现部分,return id是代码吧?在fork的函数体内,已经创建了子进程,所以会返回两份id,因为父进程也会进入fork函数,那么有了两份id,至于为什么会有“两份”,埋个伏笔~
所以得出结论,子进程的创建是用来干其他事情的,不是用来干和父进程一样的事情的。
那么我们如何创建指定量的进程呢?
如果我们采用最开始的指数级别的来创建,肯定是不好控制的,那么我们就可以使用fork的返回值,来帮助我们创建指定数量的进程。因为创建成功了,会返回0给子进程,那么我们可以让这个子进程进入到一个函数体里面再也出不来,也就不会导致子进程创建子进程的情况了:
5 void Run()6 {7 while(1)8 {9 printf("My pid is %d,ppid is %d\n",getpid(),getppid());10 sleep(1);11 }12 }13 14 int main()15 {16 for(int i = 0; i < 5; i++)17 {18 pid_t pid = fork();19 if(pid == 0)20 {21 Run();22 }23 }24 while(1) 25 {26 printf("I am a parent,my pid is %d,ppid is %d\n",getpid(),getppid());27 sleep(1);28 }return 0;}
咱们先来看结果。


不出意外的,我们创建了6个进程,主函数是第一个进程,后面通过for循环创建了5个子进程,并且5个子进程之间是没有关联的,并且通过它们各自的pid我们发现5个子进程的ppid都是父进程的12607,大胆预测的父进程的ppid的4335是bash进程,这点我们就不验证了。
好了,进程的创建我们已经基本熟络了,那么进程的大部分信息我们怎么去看呢?
首先我们引入一个问题,指令是进程吧?那么我们运行了指令之后,指令的工作路径在哪里呢?可能这个问题有点让人摸不着头脑,我们拿文件举例子,如果我们写了如下代码:
int main()
{chdir("/home/whb/111");FILE *fp = fopen("log.txt", "w");(void)fp; // ingore warningfclose(fp);while(1){printf("I am a process, pid: %d\n", getpid());sleep(1);}return 0;
}
那么log.txt文件默认会创建在哪里呢?是当前代码的工作路径吧?

在VS里面就像是这样的,那么同理,Linux中的进程工作的时候也应该有自己的工作路径,我们从哪里去看工作路径呢?
在根目录的proc里面,proc是process的缩写。

此时,我们就可以看到proc里面的信息了,如果我们要具体到某一个的进程信息,我们只需要:

同时运行其他两条指令,我们在27847父进程里面就可以注意如下事项:

本文首先注意两个,一个是cwd,一个是exe,cwd是current woek directory,当前工作目录的意思,exe就好理解了,记录对应进程中可执行文件的路径。
而当你对某一个进程进行cd的时候,发现是可以cd进去的,说明进程本质就是一个一个的目录,目录里面记录了进程的所有信息,此时,对于Linux中一切皆文件的理解又更深了一层!
感谢阅读!
相关文章:
初识Linux · 进程(3)
目录 前言: 进程的创建 前言: 继上文介绍了着重介绍了进程的内部属性,以及在操作系统层面进程如何被组织起来的,如何调用系统接口,有关task_struct,进程的部分理解等,今天,我们就…...
【spring】spring bean对象生命周期,spring容器如何管理bean,spring容器的名称是叫什么
【spring】spring bean对象生命周期,spring容器如何管理bean,spring容器的名称是叫什么 DefaultListableBeanFactory开始 spring 容器 DefaultListableBeanFactory DefaultListableBeanFactory是Spring的核心BeanFactory实现,它负责Bean的创…...
基于51单片机的电饭锅控制系统proteus仿真
地址: https://pan.baidu.com/s/1CGyg6uPhFI0MeaBWwe_HAg 提取码:1234 仿真图: 芯片/模块的特点: AT89C52/AT89C51简介: AT89C52/AT89C51是一款经典的8位单片机,是意法半导体(STMicroelectro…...
创建dataSource错误
说明:记录一次启动项目时的异常,如下: Error starting ApplicationContext. To display the conditions report re-run your application with debug enabled. 2024-09-14 23:27:27.338 ERROR 42260 --- [ main] o.s.boot.SpringA…...
为解决bypy大文件上传报错—获取百度云文件直链并使用Aria2上传文件至服务器
问题描述 一方面组内的服务器的带宽比较小,另一方面使用bypy方式进行大文件(大于15G)上传时会报错(虽然有时可以成功上传,但是不稳定): 解决方式 总体思路: 获得云盘需要下载文件的直链复制直链到服务器中使用自带…...
53.9k star 提升命令行效率的模糊搜索神器--fzf
fzf简介 作为Linux/Unix命令行的重度用户,你是否还在使用繁琐的管道命令与复杂选项组合来过滤文件和数据?其实我们有一个更简单高效的选择 - fzf。 fzf是一个开源的通用模糊搜索工具,可以大幅度提升命令行的使用体验。它的查询运行速度极快,支持预览选中的文件内容,还能与各…...
项目需求 | MySQL增量备份与恢复的完整操作指南
目录 一、MySql数据库增量备份的工作原理 1、全量备份与增量备份 2、增量备份原理 二、进行增量备份 步骤1:启用二进制日志 使用 SHOW VARIABLES 命令查看二进制日志状态 步骤2:执行增量备份脚本 三、使用增量备份恢复损坏的数据库 步骤1&#…...
判断当前环境是否为docker容器下
判断当前环境是否为docker容器下 webshell后或登录到系统后台,判断是否为docker容器可使用如下方法: 方式一:使用ls -alh命令查看是否存在.dockerenv来判断是否在docker容器环境内 ls -alh /.dockerenv如下图无.dockerenv文件,所…...
深入理解FastAPI中的root_path:提升API部署灵活性的关键配置
在Web开发领域,FastAPI因其高性能、易于使用和类型提示功能而备受开发者喜爱。然而,当涉及到在生产环境中部署FastAPI应用程序时,我们常常需要面对一些挑战,比如如何正确处理代理服务器添加的路径前缀。这时,root_path…...
QLORA:高效微调量化大型语言模型
人工智能咨询培训老师叶梓 转载标明出处 传统的16位精度微调需要超过780GB的GPU内存,对于参数量极大的模型,如65B(即650亿参数)的模型,在资源有限的情况下大模型的微调几乎是不可能的。华盛顿大学的研究者团队提出了一…...
CesiumJS+SuperMap3D.js混用实现可视域分析 S3M图层加载 裁剪区域绘制
版本简介: cesium:1.99;Supermap3D:SuperMap iClient JavaScript 11i(2023); 官方下载文档链家:SuperMap技术资源中心|为您提供全面的在线技术服务 示例参考:support.supermap.com.cn:8090/w…...
Fish-Speech 部署安装指南
Fish Speech 是由 Fish Audio 团队开发的一款开源文本转语音(TTS)模型,它在多语言支持和性能方面取得了显著的突破。根据证据显示,Fish Speech 最新版本为 1.4 版本,该版本不仅提升了对多种语言的支持,还大…...
Excel 国产化替换新方案
前言 在当前数字化转型和信创(信息技术应用创新)战略背景下,企业对于安全性、自主可控性和高效办公工具的需求日益增加。作为一款国产自主研发的高性能表格控件,SpreadJS 正成为替换 Excel 的最佳选择。它不仅全面支持国产化认证…...
在职研生活学习--20240908
文章目录 九月八日清晨,我们在鸟鸣声中醒来,精神饱满地迎接大汇演的挑战。上午,我们被分成舞龙队、旗手队、拳队、鼓队四个特色团队进行练习。阳光下,我们挥汗如雨,却乐此不疲。鼓声隆隆,龙舞飞扬ÿ…...
chattr:修改文件的特殊属性
chattr 命令用于改变文件的特殊属性,也称为"chattr 属性"。这些属性可以提供额外的安全性和控制,如设置文件为不可修改、只允许在文件末尾添加数据等。 一、Linux 文件属性 文件属性是指与文件相关联的元数据,这些属性决…...
vue-router 在新的标签页打开链接/路由
前言 vue-router 在新的标签页打开链接/路由,由于官方没有提供对链接target属性的配置,要实现这个需求,需要自行实现,这里提供几个方案供参考。 调用 API vue-router 的路由实例除了常见的 push, replace, go 等接口࿰…...
Ansys HFSS的边界条件与激励端口
本文将介绍HFSS边界条件、激励端口,然后重点介绍连接器信号完整性仿真应用最多的波端口(wave port)及其尺寸设置要点。 HFSS (电磁仿真)边界条件 HFSS中所谓的边界并非真正意义上的边界,边界条件是指定问题区域和对象边缘的场行为接口。在HFSS的背景下,边界的存在主要有两个…...
C++:线程库
C:线程库 threadthreadthis_threadchrono 引用拷贝问题 mutexmutextimed_mutexrecursive_mutexlock_guardunique_lock atomicatomicCAS condition_variablecondition_variable thread 操作线程需要头文件<thread>,头文件包含线程相关操作…...
StarRocks实时分析数据库的基础与应用
1. 什么是 StarRocks? StarRocks 是一款开源的在线分析处理(OLAP)数据库,专为实时、低延迟的分析场景而设计。它以其大规模并行处理(MPP)架构和列式存储设计,极大地提高了查询性能和处理效率。…...
golang学习笔记17——golang使用go-kit框架搭建微服务详解
推荐学习文档 golang应用级os框架,欢迎stargolang应用级os框架使用案例,欢迎star案例:基于golang开发的一款超有个性的旅游计划app经历golang实战大纲golang优秀开发常用开源库汇总想学习更多golang知识,这里有免费的golang学习笔…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
