【进程概念】启动进程 | 查看进程 | 创建进程

目录

启动进程

查看进程

方法1:/proc

方法2:查看脚本

​方法3:系统调用获取进程标示符❗❗

终止进程 

创建进程(主fork)

🙂查看父子进程的pid 

🙂进程创建/执行/终止

🙂多次重新启动进程查看pid和ppid

​🙂系统调用函数fork创建子进程 

🙂why❓fork有两个返回值

🙂父子进程执行不一样的代码 

进程的当前工作路径 


从本篇开始陆续介绍Linux中进程的task_struct本省内部的属性。 

启动进程

  • ./ 本质上就是让系统创建进程并运行。
  • myprocess.c是C语言源代码
  • myprocess是可执行文件(gcc/g++)
  • 可执行的程序的可执行文件在磁盘上
  • ./运行程序:把可执行程序加载到内存上,OS创建task_struct,进入排队,等待调度。
  • 启动程序:就是让系统创建进程并运行。
  • 我们自己写的代码形成的可执行程序 == 系统指令(都是可执行程序) == 可执行文件。
  • 在Linux中运行的大部分指令操作,本质都是运行程序。

  • 在Linux中启动进程一般make(shell命令行)

  • 在windows启动进程双击(图形化界面)

【Makefile】 

  1 myprocess:myprocess.c2     gcc -o $@ $^ -g3 .PHONY:clean4 clean:5     rm -f myprocess 

【myprocess.c】 

  1 #include<stdio.h>2 #include<unistd.h>//sleep函数包含的头文件3 int main()4 {5     //让这个进程持续运行不停止6     while(1)7     {8         printf("I am a process!\n");9         sleep(1);10     }11     return 0;                                                                                                12 }
 ./myprocessI am a process!
I am a process!
I am a process!
I am a process!
//之后myprocess已经是一个进程

【在/usr/bin/find目录下查看的可执行程序】

file /usr/bin/find

查看进程

 怎么查看进程呢?父进程,子进程?

  • 进程的信息可以通过 /proc 系统文件夹查看
  • 系统调用获取进程的标识符
  • 查看脚本

方法1:/proc

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

ls /proc/1
ls /proc/

方法2:查看脚本

大多数进程信息同样可以使用top和ps这些用户级工具来获取。

  • ps查看当前系统的进程
  • axj显示进程的详细信息(可以打乱顺序写)
  • ps axj是用户级的工具,可以行输出消息
  • grep也是一个可执行程序
  • grep可以把数据按照 行过滤的方式输出

ps axj | grep myprocess :grep把得到的进程信息数据,按照行过滤的方式,凡是包含myprocess的关键字全部提取出来。


  • head n查看前n行的信息

ps axj | head -1 查看进程信息的属性信息


  • grep -v 关键字 就是除了显示除了关键字以外的其他行信息
  • -v反向过滤
  • 不需要查看grep的进程信息,举例很混乱。

ps axj | grep -v grep


  • && 一起查看,两个命令同时进程
  • | 管道
  • 查阅出来的信息也可能含有grep的进程信息,因为grep也是一个进程。grep这个进程本省也携带了过滤myprocess的这个关键字。

  • 周期性循环查看进程脚本
  •  while :; do ps axj | head -1 && ps axj | grep -v grep | grep process; sleep 1; done
  • 清晰的看到进程的创建,执行,中止,状态这一整个连贯操作。
ps axj | grep myprocess
ps axj | head -1
ps axj | head -1 && ps axj | grep 关键字
ps axj | head -1 && ps axj | grep -v 关键字 | grep 关键字
ps axj | head -1 && ps axj | grep -v grep | grep process
//循环查看脚本
while :; do ps axj | head -1 && ps axj | grep -v grep | grep process; sleep 1; done

 方法3:系统调用获取进程标示符❗❗

  • 进程的pid:每一个进程都要有自己的唯一标识符,叫做进程pid
  • 进程的ppid(子进程的父进程的pid)
  • pid:process id 表示进程的唯一标识符
  • ppid:process parent id

  • pid和ppid同理
  • pid的类型是unsigned int,无符号整数被操作系统封装成pid_t的类型
  • pid是一个无符号整型的变量(unsigned int)
  • 每一个进程都有task_struct,每个进程间的task_struct怎么区分,用pid❗❗
  • Linux中PCB就是task_struct,进程 == 任务task
  • 用户想要知道一个进程的pid,是不能够直接到操作系统的内核数据结构中去查询的PCB的pid,需要使用操作系统提供的"系统调用接口"去查询

pid的查看

  • 使用man指令去查询getpid 和getppid:man pid 
  • ❓若查询不到,请安装man命令的一个man-pages安装包
  • 安装查看:yum install man-pages(安装的时候只能用超级管理员root安装)
  • 系统调用函数getpid查看子进程的pid
  • 用getppid查看子进程的ppid == 父进程pid     
  • #include <sys/types.h>
  • #include <unistd.h>

理解:当代码预处理,编译,汇编,链接形成可执行程序的文件的时候是在磁盘中存放,这个时候还不是进程,也没有运行一行代码。只有可执行程序加载到内存,OS创建进程启动进程调度进程的时候。进程启动起来,系统调用函数才会获得PCB的pid。

  • 操作系统OS没有PCB,操作系统内核有定期的任务。比如刷新,内存管理之类这些有PCB,操作系统OS本身不需要PCB
yum install man-pages //记得指令提权
man pid
man 2 pid 


【用系统调用函数查看进程的pid】

  1 #include<stdio.h>2 #include <sys/types.h>3 #include <unistd.h>4 5 int main()6 {7     pid_t id=getpid();8     //让这个进程持续运行不停止9     while(1)10     {11         printf("I am a process!,pid=%d\n",id);     12         sleep(1);13     }14     return 0;15 }

终止进程 

  • ctrl+c就是在用户层面终止进程
  • kill -9 pid 可以用来直接杀掉进程 

创建进程(主fork)

进程创建的代码方式

(这里讲解重点在操作,轻微原理。后面会重谈进程的创建以及其他方法)

  • pid_t getpid(void);获得当前进程的pid
  • pid_t getppid(void);获得当前进程的父进程的pid
  • 父进程VS子进程
  1. bash是父进程,进程创建进程
  2. 系统调用函数创建进程

🙂查看父子进程的pid 

  1 #include<stdio.h>2 #include <sys/types.h>3 #include <unistd.h>4 5 int main()6 {7     pid_t id=getpid();8     pid_t parentid=getppid();9     //让这个进程持续运行不停止10     while(1)11     {12         printf("I am a process!,pid=%d,ppid:%d\n",id,parentid);                      13         sleep(1);                                                     14     }                                               15     return 0;                                       16 } 

🙂进程创建/执行/终止

while :; do ps axj | head -1 && ps axj | grep -v grep | grep process; sleep 1; done

🙂多次重新启动进程查看pid和ppid

❓我们发现每次重新启动进程,进程的pid都要改变,但是进程的父进程pid都不改变。

❓查询父子进程属性信息:发现都有bash进程

  • 进程每次启动,对应的pid都不一样是正常的
  • 经过验证,我们创建的进程的父进程就是bash
  • bash是父进程,是实习生,是李婆,命令行解释器。
  • ❗所以进程可以创建进程。
ps axj | head -1 && ps axj | grep -v grep | grep 13185//查询父进程
ps axj | head -1 && ps axj | grep -v grep | grep 12345 //查询子进程随机一个

🙂系统调用函数fork创建子进程 

  • 创建一个进程,OS内多了进程,多了进程的PCB,内存多了进程的代码和数据。
  • 用户想要创建进程,就要创建内核数据结构,用户是没有权力对操作系统内部的内核数据结构等做增删查改的。
  • 所以,用户只能使用OS提供的系统调用函数来创建子进程。
  • fork:分支,叉子。创建子进程。
  • man fork
  • 头文件:  #include <unistd.h>
  • 返回值有两个类型都是pid_t
  • 可以接收返回值,也可以不接收。

fork创建子进程的脑中图,理解记忆❗

  • 在fork创建了子进程,是由父子进程分别都要执行后序代码,它们共享一份代码。
  • 创建一个进程,本质是系统中多一个进程,那么内存也会多一份代码和数据。
  • 父进程的代码和数据是从磁盘中加载过来的
  • 父进程的PBC也是OS动态创建的

❓子进程的代码和数据,PBC呢?

  • 子进程的代码和数据也可以从磁盘再加载一份到内存(下个博文进程控制会讲)
  • 在fork这里默认子进程的代码和数据是继承父进程的
  • 数据也是继承的吗❓

所以,fork()之后,父子进程代码共享。理论上,子进程是在fork之后共享了父进程的代码和数据,OS才动态创建了子进程的PCB

  1 #include<stdio.h>2 #include <sys/types.h>3 #include <unistd.h>4 5 int main()6 {7     printf("process is running,only me!\n");//只有父进程8     sleep(3);9     fork();//创建子进程10     printf("hello linux\n");11     sleep(5);                                                                                   20     return 0;21 }

  1 #include<stdio.h>  2 #include <sys/types.h>  3 #include <unistd.h>  4   5 int main()  6 {  7     pid_t id=getpid();  8     pid_t parentid=getppid();                                                                   9     printf("process is running,id=%d,parentid=%d\n",id,parentid);//只有父进程  10     sleep(3);                                                 11     fork();//创建子进程                                       12     printf("hello linux,id=%d,parentid=%d\n",id,parentid);    13     sleep(5);                                                                                                       22     return 0;                                                 23 }                                                             
~      

🙂why❓fork有两个返回值

🙂父子进程执行不一样的代码 

进程的当前工作路径 

🙂感谢大家的阅读,若有错误和不足,欢迎指正。 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32 CAN的工作模式

STM32 CAN的工作模式 正常模式 正常模式下就是一个正常的CAN节点&#xff0c;可以向总线发送数据和接收数据。 静默模式 静默模式下&#xff0c;它自己的输出端的逻辑0数据会直接传输到它自己的输入端&#xff0c;逻辑1可以被发送到总线&#xff0c;所以它不能向总线发送显性…

鸿蒙开发实战:网络请求库【axios】

简介 [Axios] &#xff0c;是一个基于 promise 的网络请求库&#xff0c;可以运行 node.js 和浏览器中。本库基于[Axios]原库v1.3.4版本进行适配&#xff0c;使其可以运行在 OpenHarmony&#xff0c;并沿用其现有用法和特性。 http 请求Promise APIrequest 和 response 拦截器…

Stable Diffusion实现光影字效果

昨天下午有人在群里发光影图片&#xff0c;大家都觉得很酷&#xff0c;我没怎么在意。直到早上我在小红书看到有人发同款图片&#xff0c;只是一晚上的时间点赞就超过了8000&#xff0c;而且评论数也很高&#xff0c;也可以做文字定制变现。研究了一下发现这个效果不难实现&…

数据结构/C++:哈希表

数据结构/C&#xff1a;哈希表 哈希表概念哈希函数直接定址法除留余数法 哈希冲突闭散列 - 开放定址法基本结构查找插入删除总代码展示 开散列 - 哈希桶基本结构查找插入删除代码展示 哈希表概念 在顺序表中&#xff0c;查找一个数据的时间复杂度为O(N)&#xff1b;在平衡树这…

宋仕强论道之华强北科技创新说

宋仕强论道之华强北科技创新说&#xff0c;“创新”是深圳市和华强北灵魂&#xff0c;创新再加上敢想敢干永不言败&#xff0c;造就了深圳市经济奇迹和华强北财富神话&#xff01;首次在深圳市落槌的“土地拍卖”&#xff0c;华强北“一米柜台”赋予独立经营权&#xff0c;把最…

通过jsDelivr实现Github的图床CDN加速

最近小伙伴们是否发现访问我的个人博客http://xiejava.ishareread.com/图片显示特别快了&#xff1f; 我的博客的图片是放在github上的&#xff0c;众所周知的原因&#xff0c;github访问不是很快&#xff0c;尤其是hexo博客用github做图床经常图片刷不出来。一直想换图床&…

提面 | 面试抽题

学习到更新日期面试抽题-1.2案例分析的思维本质2024-3-23 1提面抽屉论述问题的分类 1.1案例分析占总论 1.2案例分析的思维本质

rabbitmq 3.9.29 docker mac 管理员页面无法打开

SyntaxError: Unexpected token ‘catch’ SyntaxError: Unexpected token ‘catch’ at EJS.Compiler.compile (http://127.0.0.1:15672/js/ejs-1.0.min.js:1:6659) at new EJS (http://127.0.0.1:15672/js/ejs-1.0.min.js:1:1625) at format (http://127.0.0.1:15672/js/main…

【docker系列】深入理解 Docker 容器管理与清理

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

llvm后端

SelectionDAGBuilder是LLVM&#xff08;Low Level Virtual Machine&#xff09;编译器中的一个重要组件&#xff0c;它负责将LLVM中间表示&#xff08;Intermediate Representation&#xff0c;IR&#xff09;转换为SelectionDAG&#xff08;选择有向无环图&#xff09;的形式。…

java selenium 元素点击不了

最近做了一个页面爬取&#xff0c;很有意思被机缘巧合下解决了。 这个元素很奇怪&#xff0c;用xpath可以定位元素&#xff0c;但是就是click()不了。 试过了网上搜的一些办法&#xff1a; //尝试一 WebElement a_tag driver.findElement(By.xpath("xxx")); a_tag…

适合马犬吃的狗粮有哪些?

亲爱的朋友们&#xff0c;你们是不是也在为家里的马犬挑选合适的狗粮而犯愁呢&#xff1f;&#x1f436;&#x1f35a; 今天&#xff0c;我就来和大家分享一下适合马犬吃的狗粮有哪些&#xff0c;以及为什么我要特别推荐福派斯鲜肉无谷狗粮。 首先&#xff0c;我们得了解马犬的…

ArmSoM-Sige RK3588开发板产品简介

让我们在 5 分钟内了解 Sige7。 简介​ ArmSoM-Sige7采用Rockchip RK3588新一代旗舰级八核64位处理器&#xff0c;主频高达2.4GHz&#xff0c;6 TOPS算力NPU&#xff0c;最大可配32GB大内存。支持8K视频编解码&#xff0c;拥有丰富的接口&#xff0c;支持双2.5G网口、WiFi6 &…

【leetcode热题】 二叉树的右视图

给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 示例 1: 输入: [1,2,3,null,5,null,4] 输出: [1,3,4]示例 2: 输入: [1,null,3] 输出: [1,3]示例 3: 输入: [] 输出: []解法一 题…

InstructGPT的流程介绍

1. Step1&#xff1a;SFT&#xff0c;Supervised Fine-Tuning&#xff0c;有监督微调。顾名思义&#xff0c;它是在有监督&#xff08;有标注&#xff09;数据上微调训练得到的。这里的监督数据其实就是输入Prompt&#xff0c;输出相应的回复&#xff0c;只不过这里的回复是人工…

element-ui checkbox 组件源码分享

简单分享 checkbox 组件&#xff0c;主要从以下三个方面来分享&#xff1a; 1、组件的页面结构 2、组件的属性 3、组件的方法 一、组件的页面结构 二、组件的属性 2.1 value / v-model 属性&#xff0c;绑定的值&#xff0c;类型 string / number / boolean&#xff0c;无…

Spring单元测试+Mockito

一&#xff0c;背景 单元测试基本上是开发逃不过的一个工作内容&#xff0c;虽然往往因为过于无聊&#xff0c;或者过于麻烦&#xff0c;而停止于项目的迭代之中&#xff0c;不了了之了。其实不是开发们懒&#xff0c;而是上头要求的测试覆盖率高&#xff0c;但是又没有好用的…

Stable Diffusion 本地训练端口与云端训练端口冲突解决办法

方法之一&#xff0c;修改本地训练所用的端口 1 首先&#xff0c;进入脚本训练器的根目录 例如&#xff1a;C:\MarkDeng\lora-scripts-v1.7.3 找到gui.py 2 修改端口号 因为云端训练器也是占用28000和6006端口 那么本地改成27999和6007也是可以的 保存退出&#xff0c;运行启动…

扩展一下BenchmarkSQL,新增支持ASE/HANA/DB2/SQLServer,可以随便用了

1 背景 提到数据库的性能,自然就避不开性能测试。有专用于测试OLTP的,也有偏重于OLAP的。本文介绍的BenchmarkSQL就属于测试OLTP中的一个,基于TPCC的。网上有很多介绍TPC*的相关测试的文章,大家可以自行脑补。而PostgreSQL自带的pgbench是属于TPCC的前一个基准测试程序,偏…

机器学习基础知识面经(个人记录)

朴素贝叶斯 特征为理想状态下的独立同分布&#xff0c;作为机器学习的重要基石和工具 由贝叶斯公式推导而来 是后验概率&#xff1a;在B发生的条件下A发生的概率。 是似然概率: 在 发生的条件下 发生的概率。 是先验概率: 发生的概率&#xff0c;而不考虑 的影响。 是…