【Linux】进程的基本概念

目录

概念

课本概念: 程序的一个执行实例,正在执行的程序等。(就是执行任务)

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

  1. 我们写完代码后经过编译和链接后形成一个可执行文件,打开这个可执行文件就会加载到内存中交给CPU处理,CPU才能对其进行逐行的语句执行,而一旦将这个程序加载到内存后,我们就不应该将这个程序再叫做程序了,严格意义上将应该将其称之为进程。

描述进程-PCB

  1. 系统当中可以同时存在大量进程,使用命令ps aux便可以显示系统当中存在的进程。
  2. 而我们开机第一个运行的就是操作系统,运行操作系统就是一个进程。我们都知道操作系统是软件和硬件的管理者,那么进程也是操作系统来管理的。那么操作系统到底是如何来管理进程的呢?
  3. 这时我们就应该想到管理的六字真言:先描述,再组织t操作系统也是一样的,操作系统并不需要直接的和进程见面进行管理,而是对进程的属性进行描述,而操作系统只需要对这些描述的信息进行管理就行了。
  4. 那么描述进程属性是存放在哪里的呢。他是存放在一个叫做PCB的数据结构中,在Linux操作系统下,我们把他称为task_struct.
  5. 操作系统将每一个进程都进行描述,形成了一个个的进程控制块(PCB),并将这些PCB以双链表的形式组织起来。

    把这些PCB用双链表组织起来,那么我们只需要遍历双链表就可以访问到所有的PCB,如果我们要删除某个进程的信息,就是删除双链表对应的节点,所以对进程的管理实际上就是数据结构的增删查改。

如何查看进程

通过系统目录进行查看

  • 在根目录下有一个叫做proc的文件,这里面就是我们Linux下的所有进程
  • 这些进程的名字有的名字是一个数字,这些数字其实就是进程的PID(可以理解为身份证)
  • 如果我们想要查看进程的信息,就可以用ls指令来显示这些文件,这就是进程的信息

通过ps指令进行查看

  • 单独使用ps命令,会显示所有进程信息。
  • ps命令与grep命令搭配使用,即可只显示某一进程的信息。
bash 复制代码
ps aux | head -1 && ps aux | grep proc
  • 解释一下这个命令,ps aux拿到所有进程信息, |是管道,意思是把ps aux拿到的数据的输出作为 head -1 的输入,head -1 表示只取输入内容的第一行,也就是进程信息列表的表头 ,比如 F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 。交给下个指令
  • && :是逻辑与操作符,表示只有当左边的指令执行成功的时候才执行右边的指令
  • ps aux | grep proc, 当ps aux执行成功列出了所有的进程信息后把他的输出(所有的进程信息)作为给grep指令的输入,grep去查找这些进程信息中,proc名字的进程

通过系统调用获取进程的PID和PPID(进程标⽰符)

  • 通过使用系统调用函数,getpid(自己的身份)和getppid(父进程的身份)即可分别获取进程的PID和PPID。
    我们可以通过一段代码来进行测试。
  • 当运行该代码生成的可执行程序后,便可循环打印该进程的PID和PPID。

通过系统调用创建子进程

通过一段代码来介绍fork


  • 这个时候你会发现,if和else if居然在同时运行

    这是为啥呢?在我们写过的程序中,怎么可能同时满足if又满足else if, 接下来我们就要对于这个现象进行剖析

为什么要有子进程?

之所有要有子进程,其实就是父进程想让子进程去绑他做一些事情,也就是说在父进程做事情的同时,子进程也可以同时做事情,父进程和子进程分别去做不同的事情。 那我们说完成一个任务总有知道是谁完成的吧,所以子进程和父进程都要有一个返回值。用来区分这个进程是子进程还是父进程。

  • 解决方法就是fork要有两个返回值!!------>所以返回不同的值的意义是为了区分不同的执行流,让父进程和子进程分别执行不同的代码块!!

fork为什么给子进程返回0,给父进程返回子进程的PID

因为在Linux系统中父进程和子进程的关系是1:n的,也就是说父进程可以有1个或多个子进程,但是子进程的父进程只能有1个。父进程如果有多个子进程,那么这个父进程就要通过这些子进程的pid来区分不同的子进程进行管理。而如果是子进程为啥返回0,因为子进程不需要父进程的pid,他可以通过getpid这个函数来获得。

fork函数到底做了啥?

  • 因为fork函数会创建一个进程,而进程=(内核数据结果)+代码和数据,所以首先:
    1. 创建一个task_struct结构体
    2. 吧进程的属性填写到task_struct里面
    3. 让子进程和父进程指向同样的代码,因为子进程继承了父进程的大多数属性。(跟子进程拷贝父进程的PCB有一定的关系,就是继承了pcb里面的属性,还有进程的地址空间,页表这些), 所以这里fork创建子进程后的代码是父进程和子进程共享的,那么return就会return两次,父进程return1次,子进程return1次。
    4. 这个时候补充一个知识:因为进程之间具有独立性,也就是说进程之间不能互相影响(比如说我关掉了洛谷这个进程并不影响我在爱奇艺上看电视),所以上面fork函数返回两次给id这个变量就会导致子进程修改一次,父进程修改一次。
    5. 这个时候就发生了写时拷贝

任何平台,进程都是具有独立性的,在子进程和进程共享代码的时候,因为代码是只读的,这是没有问题的。但是数据就不一样了,数据可以修改。那这个时候数据也是共享的,他们其中的一个改了数据就不行了。所以说,我们的子进程/父进程如果想要修改数据,就要想办法把修改的数据拷贝一份出来,让其指向新拷贝出来的那一块数据。这样才能做到进程之间互相不影响

一个函数是如何做到返回两次的?

  • 父子的代码是共享的,所以return ret也是属于代码,因此父子进程各返回了一次!

一个变量为什么会有不同的内容?

  • 这就是因为子进程修改了数据导致触发了写时拷贝,导致一个变量会有两个值。但是有人说不对呀,变量地址不都是一样的吗?一个物理地址,怎么会有两个值?这就要等我后面说虚拟地址空间的时候来解释了
  • 但是要注意的是,子进程被创建好之后,究竟是先运行子进程还是先运行父进程,其实是由调度器(因为CPU只有一个,所以他的作用就是在当前进程中选一个合适的放到CPU中,进程之间会竞争CPU资源,所以调度器会遵循着自己的一套原则来保证进程之间的公平性)这个后面我会在进程优先级讲解

通过fork来理解bash的命令行是如何来工作的?

  • bash这个进程主要是用于做命令行解析的工作,bash创建一个子进程来替他执行指令操作,因为进程的独立性就是子进程失败了也不会影响bash这个进程。这样就达到了让bash这个进程专注于命令行解释的工作。
  • 什么事命令行解释?

end

感谢你的阅读,如果对你有帮助的话,给博主点一个赞吧。

相关推荐
大树886 小时前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠6 小时前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质7 小时前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
bush47 小时前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5207 小时前
Linux 11 动态监控指令top
linux
小宇宙Zz7 小时前
Maven依赖冲突
java·服务器·maven
Inhand陈工8 小时前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
酣大智8 小时前
ARP代理--工作原理
运维·网络·arp·arp代理
不会C语言的男孩8 小时前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言
shushangyun_8 小时前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化