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

目录

启动进程

查看进程

方法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.c
  2     gcc -o $@ $^ -g
  3 .PHONY:clean
  4 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 }
 ./myprocess

I 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有两个返回值

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

进程的当前工作路径 

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

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

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

相关文章

java的IO之NIO

NIO是一种同步非阻塞的I/O模型&#xff0c;在Java 1.4中引入了NIO框架&#xff0c;对应java.nio包&#xff0c;提供了channel、selector、buffer等。 NIO中的N可以理解为Non-blocking不在单纯是New&#xff0c;它支持面向缓冲的&#xff0c;基于通道的I/O操作方法。NIO提供了与…

论文阅读之LORA: LOW-RANK ADAPTATION OF LARGE LAN- GUAGE MODELS(2021)

文章目录 论文地址主要内容主要贡献模型图技术细节实验结果 论文地址 LORA: LOW-RANK ADAPTATION OF LARGE LAN- GUAGE MODELS 主要内容 这篇文章的主要内容是介绍了一种名为LoRA&#xff08;Low-Rank Adaptation&#xff09;的技术&#xff0c;这是一种针对大型语言模型进行…

阅读MySQL知识4

一、MySQL数据库主从同步延迟产生的原因 MySQL的主从复制都是单线程的操作&#xff0c;主库对所有DDL和DML产生的日志写进binlog&#xff0c;由于binlog是顺序写&#xff0c;所以效率很高。 Slave的SQL Thread线程将主库的DDL和DML操作事件在slave中重放。DML和DDL的IO操作…

【欧拉函数+快速幂】第十四届蓝桥杯省赛C++ C组 Java A组/研究生组 Python 研究生组《互质数的个数》(C++)

【题目描述】 给定 a,b&#xff0c;求 1≤x< 中有多少个 x 与 互质。 由于答案可能很大&#xff0c;你只需要输出答案对 998244353 取模的结果。 【输入格式】 输入一行包含两个整数分别表示 a,b&#xff0c;用一个空格分隔。 【输出格式】 输出一行包含一个整数表示…

8-深度学习

声明 本文章基于哔哩哔哩付费课程《小白也能听懂的人工智能原理》。仅供学习记录、分享&#xff0c;严禁他用&#xff01;&#xff01;如有侵权&#xff0c;请联系删除 目录 一、知识引入 &#xff08;一&#xff09;深度学习 &#xff08;二&#xff09;Tensorflo…

Java全栈课程之Linux———基本属性

一、看懂文件属性 Linux系统是一种典型的多用户系统&#xff0c;不同的用户处于不同的地位&#xff0c;拥有不同的权限。为了保护系统的安全性&#xff0c;Linux系统对不同的用户访问同一文件&#xff08;包括目录文件&#xff09;的权限做了不同的规定。 在Linux中我们可以使…

深入理解Ubuntu22:探索Linux操作系统的功能与应用

一、linux &#xff08;一&#xff09;、安装 1、电脑可以安装双系统&#xff0c;即在一套硬件上只能同时运行一个操作系统&#xff0c;例&#xff1a;C盘安装win&#xff0c;D盘安装linux。 2、虚拟机 虚拟机需要硬件支持&#xff0c;并需开启VT-x. 如&#xff1a;Virtual…

Ubuntu18.04显示--有线连接未托管

引用: Ubuntu18.04连不网 报"有线连接未托管"_ubuntu20.04以太网未托管-CSDN博客 正文 虚拟机环境配置&#xff1a; VirtaualBox Ubuntu18.04桌面版 问题现象&#xff1a; Ubuntu18.04虚拟机的桌面上提示“有线连接未托管”&#xff0c;虚拟机不能上网&#xf…

使用倒模耳机壳UV树脂胶液制作舞台监听耳返入耳式耳机壳有哪些缺点?

使用倒模耳机壳UV树脂胶液制作舞台监听耳返入耳式耳机壳也存在一些缺点&#xff0c;具体如下&#xff1a; 成本较高&#xff1a;相对于传统的塑料或金属材料&#xff0c;UV树脂胶液的成本较高&#xff0c;需要更多的材料和工艺成本。制作难度较大&#xff1a;由于UV树脂的特殊…

鸿蒙ArkTS实战开发-Native XComponent组件的使用

介绍 本篇Codelab主要介绍如何使用XComponent组件调用NAPI来创建EGL/GLES环境&#xff0c;实现在主页面绘制一个正方形&#xff0c;并可以改变正方形的颜色。本篇CodeLab使用Native C模板创建。 如图所示&#xff0c;点击绘制矩形按钮&#xff0c;XComponent组件绘制区域中渲…

校招岗位大解析

校园招聘岗位需要综合考虑岗位描述、行业背景、公司文化、职业发展路径、技能要求、薪酬福利以及公司口碑等多个方面的因素&#xff0c;全面了解并综合考虑这些因素&#xff0c;才能更好地选择适合自己的岗位&#xff0c;实现个人职业发展目标。 1. 软件/后端/前端开发 软件/…

【SpringBoot】如何定义接口

定义get接口 使用GetMapping定义一个基本get接口 RestController //表示定义一个json格式返回给前端 public class test {private Map<String,Object> map new HashMap<>();GetMapping(value "/test") //定义接口路径public Object userInfo(Strin…

搭建Linux内核开发环境——保姆教程(持续更新中)

搭建Linux内核开发环境——保姆教程&#xff08;持续更新中&#xff09; git版本管理汇编器链接器调试器编辑器构建系统模拟器文档工具图形设计工具 在此文中&#xff0c;持续完善&#xff0c;搭建内核开发环境的细节&#xff0c;有需要的小伙伴儿可以持续关注下 git版本管理 …

【小白入门篇1】GPT到底是怎样练成?

由于具有代表性的OpenAI公司GPT模型并没有开源&#xff0c;所以本章节是参考一些开源和现有课程&#xff08;李宏毅&#xff09;讲解ChatGPT原理。本章没有涉及到很多数学运算&#xff0c;比较适合小白了解GPT到底是怎么练成。GPT的三个英文字母分别代表Generative(生成式)&…

【LeetCode】升级打怪之路 Day 27:回溯算法 — 单词拆分问题

今日题目&#xff1a; 140. 单词拆分 II139. 单词拆分 参考文章&#xff1a;回溯算法&#xff1a;单词拆分 今天主要做了两道单词拆分的问题&#xff0c;都是需要使用回溯算法来解决&#xff0c;第一个题目难度不大&#xff0c;第二个题目需要在“剪枝”上多做一些功夫&#xf…

电脑共享文件使用记录怎么查

共享文件是指在网络环境下&#xff0c;多台计算机之间或同一台计算机的不同用户之间&#xff0c;能够对文件进行共享的一种机制。 通过共享文件&#xff0c;用户可以方便地在多台计算机之间传输和访问文件&#xff0c;实现文件资源的共享和协作。 在共享文件的设置中&#xf…

基于modbus TCP实现EPICS与西门子S7 1200系列1215C PLC的通信

PLC介绍 西门子系列PLC在国内的市场占比第一&#xff0c;1200系列中小型PLC&#xff0c;因其众多的产品序列、强大的通讯功能和丰富扩展模块&#xff0c;被使用在工业生产、自动化生产线、智能制造、机器人等各行各业。根据CPU的供电电源的型号和数字量输出的类型&#xff0c;…

FANUC机器人零点标定的基本步骤(出厂数据)

FANUC机器人零点标定的基本步骤(出厂数据) FANUC 零点数据存在问题的机器人通常会出现以下几种报警: (1)SRVO-062报警 - 脉冲编码器数据丢失,机器人完全不能动,具体消除方法可参考以下链接中的内容: FANUC机器人SRVO-062报警原因分析及处理对策 (2)SRVO-075报警 -…

某智慧化平台实施方案—资料原件word

1.概述 2.项目介绍 3.项目实施 4.实施计划 5.人员培训 6.项目验收 7.售后服务 8.项目保障措施 软件全套资料原件获取进主页。

软件测试 -- Selenium常用API全面解答(java)

写在前面 // 如果文章有问题的地方, 欢迎评论区或者私信指正 目录 什么是Selenium 一个简单的用例 元素定位 id定位 xpath定位 name定位 tag name 定位和class name 定位 操作元素 click send_keys submit text getAttribute 添加等待 显示等待 隐式等待 显示等…