初识Linux · 进程(2)
目录前言:
有关进程的相关明白
前言:
本文会开始慢慢切入进程了,固然,切入进程之前,我们需要再次复习一下操纵系统,后面接着是先容什么是进程,如何查看进程,在Linux中对应的文件是哪个等相关的问题,进程大概会持续更新多节,以是说进程的知识点还是相称杂乱的,就更需要同学们予以注意了。
有关进程的相关明白
首先,我们需要知道,为什么需要操纵系统?
操纵系统的工作是实行软硬件资源的管理,如何管理硬件上文提及的是通过驱动步伐,使得硬件的相关数据构造成为一个链表,操纵系统可以直接对链表的信息进行修改,驱动步伐再对硬件实行管理,这是先形貌再构造,从而实现了管理硬件,那么这是操纵系统的一个手段,也就是管理硬件的一个手段而已,它本质上还是要为用户提供精良的,稳固的,高效的,安全的服务,以是需要对相关的资源使用相应的手段进行管理。这是操纵系统的目的和手段。
由上文的操纵系统的布局图我们可以知道,操纵系统里面有进程管理以及各种管理,那么操纵系统管理进程的时间,肯定是允许多进程存在的,比如:
https://i-blog.csdnimg.cn/direct/71cf3095d16548ab931f5beb0ebd7a8a.png
这些,都是进程,想看你的电脑里面存在哪些进程,你只需要esc + shift + ctrl打开任务管理器即可,以是如今可以证明,进程是可以存在多个的。
那么,什么是进程呢?
这里提问,如果将某个工程的数据和代码加载到内存里面,代码是否会跑起来呢?固然是不会的,由于cpu并没有从里面读取数据,当代码跑起来的时间,就存在了一个进程,难道进程是对应的,已经跑起来的步伐吗?固然不是,这是不废话,进程 = PCB + 本身的代码和数据。
那么什么是PCB呢?这就有意思了,类比硬件,操纵系统管理硬件的时间,需要硬件的信息,从而构建一个链表,再对链表的相关信息增删查改,从而实现管理硬件,那么必然存在一个布局体吧?由于只有布局体可以用来存储多个不同的数据类型。
从而,推理出PCB是对应数据集合的布局体,那么PCB的全称是:process control block 。也就是进程控制块,这就有意思了,进程控制块?不就是布局体吗,那为什么取个进程控制块呢?就是由于操纵系统可以直接对PCB进行修改删除等操纵,达到对进程控制的效果。
得出结论:进程 = PCB + 本身的代码和数据。
那么为什么要有PCB的概念呢?
由于:先形貌再构造!
以是可以在内存块里面,多个进程之间以链表的情势进行毗连,每个PCB里面都有下一个PCB的指针,那么操纵系统可就轻松了,原来那么多不着头脑的进程,这下可以直接通过管理链表来实现管理进程了。
那么具体的PCB的名字是什么呢?是task_struct。
叫做task是由于外国人认为这是个任务嘛,以是就取名为task了。
进程都是动态运行的,我们如何明白动态运行这个概念呢?
是这样的,在内存块里面,OS占有一席之地,在里面实现对各种软硬件的管理,如今不同的进程进来了,总得有个先后队列吧?
以是存在task_queue的东西,也就是进程队列,不同的进程需要列队的,动态实际上就是多个PCB列队的过程。
https://i-blog.csdnimg.cn/direct/f0d4b48cf7924fbaa948902d136bb699.png
具体的会放在后面先容。
如今再来谈谈task_struct的内下属性:
首先认识一个点,我们不管是运行指令也好,运行本身编写的代码也好,本质上都是直接创建一个进程,不过指令是一瞬间就运行完成的,我们看不到相关的东西而已,那么什么进程那么多,我们如何区分不同的进程呢?像学校那样,我们每个人都有本身独一无二的学号,进程是同理的,存在一个东西叫做pid,即process id,进程的id,类比学生的学号即可。
说了那么多,我们应该如何看到pid呢?
在此之前,我们应该回想上篇文章先容的系统调用接口:
https://i-blog.csdnimg.cn/direct/95b0cb27fbb7425783b0d3599bd0aaeb.png
我们知道系统调用是操纵系统给我们的函数,我们如今从未调用过它,如今,就是调用我们人生中第一个系统调用接口的时间了,我们使用man手册查询可知:
https://i-blog.csdnimg.cn/direct/1dbd4ad67c5b427b9db787012d494cfa.pnghttps://i-blog.csdnimg.cn/direct/ea9eaba2f62f49bfb5a46e1a82f5e7e0.png
从手册的说明书我们就知道2号接口是系统库函数调用,也就是我们即将学习的getpid:
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <unistd.h>
4
5 int main()
6 {
7 printf("I am a process\nMy pid is %d\n",getpid());
8 return 0;
9 }
有意思的还有getpid()函数居然需要两个头文件一起才能使用。
https://i-blog.csdnimg.cn/direct/b2887ff4a2814bf6b2ca170ca72d677c.png
欸,打印结果也是正常,打印的进程id每次都是不一样的,我们的初步目的已经达成了,但是进程肯定是不止就这么点东西的,以是我们应该输入ps -xaj 来看,这里先记着,xaj的次序无所谓:
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <unistd.h>
4
5 int main()
6 {
7 while(1)
8 {
9 printf("I am a process\nMy pid is %d\n",getpid());
10 sleep(1);
11 }
12 return 0;
13 }
首先改一下代码,死循环方便我们观察:
https://i-blog.csdnimg.cn/direct/ab694589e46f48a3a1c8e624e0ac2e5b.png
我们使用管道来筛选出包含test的进程,前两个我们是可以明白的,但是为什么grep也有呢?由于ps -xaj打开了进程,通过管道筛选,筛选也是一个进程,那么我们想要不看它,就可以:
https://i-blog.csdnimg.cn/direct/7e0c573962af4fae9dbf6f5a67113319.png
grep -v grep反向筛选出不含grep的即可:
https://i-blog.csdnimg.cn/direct/b22ec5a847f74d778ef36ca0a63a8d6d.png
固然了,直接ps -xaj就相称于windows里面的任务管理器,查看所有进程。
我们可以看到,打印出来的pid是14191,在打印出来的head -1中也有pid,也是14191,以是pid打印出来是没问题的。
如今我们再来查看,ppid是个什么东西?ppid全程就是parent process id,也就是父进程的id,有人就有问题了,父进程?这个东西还带有继承的?我们是可以在一个进程中创建多个进程的,用到的函数是fork():
https://i-blog.csdnimg.cn/direct/4f0e3aed48c64d3682c1e9da4a6f55dd.png
这里有个很有意思很有意思的点,会颠覆你的编程三观的,即这个返回值pid_t,类型本质上是unsigned int,这里就先留个伏笔。
我们先来看一段有意思的代码:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
printf("I am a father process!\n");
fork();
printf("I am a child process\n");
return 0;
}
试问这段代码的运行结果是什么?
直接看结果:
https://i-blog.csdnimg.cn/direct/75f0a59b118b4cc0a9e96fc07b0ad905.png
可以发现打印了两遍第二次的printf,我们可以这样明白,我是一个公司老板,我在没有招员工之前不停再做雷同的事,找了员工之后,员工和我做雷同的事,但是我之前做的以是工作员工还需要做吗?不需要,以是第一行的printf是不会实行的,父进程原来的代码就是要实行printf的,以是会打印两次child process。
7 while(1)
8 {
9 printf("This is parent process:%d\nThis is child process:%d\n",getppid(),getpid());
10 sleep(1);
11 }
https://i-blog.csdnimg.cn/direct/1e4bc782135b463e9a7b3a0baf2dc5ff.png
打印出来,对应的父进程的id是22252,子进程id是22239,在ppid 和 pid 下面也得到了验证。
更多的请看后面!!!
感谢阅读!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]