Linux进程理解[冯诺依曼体系结构,操作系统,进程概念和基本操作]
- 一.冯诺依曼体系结构
- 1.冯诺依曼体系结构的说明
- 2.冯诺依曼体系结构的价值
- 1.冯诺依曼之前的计算机的局限
- 2.为什么在计算机体系结构当中要存在内存?
- 二.操作系统
- 1.什么是操作系统
- 2.操作系统如何进行管理
- 3.为什么要有操作系统
- 4.系统调用接口和用户操作接口
- 三.进程理解
- 1.进程的概念
- 2.task_struct结构体独特的链接方式
- 3.task_struct内容分类(粗略的谈一下)
- 四.进程基础的相关操作
- 1.查看进程
- 2.杀死进程
- 五.进程PID
- 1.getpid()和getppid()
- 2.fork()函数创建进程
- 1.fork()函数
- 2.演示
- 3.几点说明
- 1.进程的独立性
- 2.关于fork函数返回值的几个问题
- 1.为何给父子进程的返回值是不同的?
- 2.fork函数为何会返回2次?
- 3.为何id作为同一个变量既可以表示父进程id,又可以表示子进程id呢?
- 4.创建多个子进程(观察进程的创建和退出的全过程)
- 六.另一种查看进程的方法
- 1./proc
- 2.exe链接文件
- 3.如何改变cwd呢?
- 七.总结
要了解进程,我们首先要先了解两大知识点:
1.冯诺依曼体系结构(从硬件的角度来谈)
2.操作系统(从软件的角度来谈)
一.冯诺依曼体系结构
1.冯诺依曼体系结构的说明
2.冯诺依曼体系结构的价值
要了解冯诺依曼体系结构的价值,首先我们要先明确两点:
1.冯诺依曼之前的计算机的局限
可是在基于冯诺依曼体系结构设计的计算机出现之前
计算机有两大不足之处:
1.效率低
2.贵
为什么会这样呢?
这是从网上找的一张计算机的存储金字塔
它详细的说明了一个道理:
当时的计算机只有CPU和输入设备,输出设备
而且大家可能都听说过木桶原理
2.为什么在计算机体系结构当中要存在内存?
因此内存的引入使得我们的计算机的整体效率还不错,而且还比较便宜,这也就利于计算机的传播
使用计算机的人越来越多,因此才出现了互联网
至此,我们就将理解进程前冯诺依曼体系结构相关的前置知识介绍完毕
下面我们来谈一下第二个前置知识:操作系统
二.操作系统
1.什么是操作系统
这里的驱动程序是指:
操作系统可以通过调用对应底层硬件对应的驱动程序的接口来实现对底层硬件的访问与控制
因此把操作系统可以通过驱动程序来保证对硬件管理的高效性和成功率
2.操作系统如何进行管理
至此,我们就了解了操作系统是如何进行软硬件资源管理的了
那么接下来的问题是:
操作系统跟用户之间是什么关系呢?
下面我们就说明操作系统跟用户之间的关系:
3.为什么要有操作系统
4.系统调用接口和用户操作接口
至此,大家对于这张图片的理解就会更加深刻了
我们将理解进程前操作系统相关的前置知识介绍完毕了
下面我们正式进入进程的学习当中
三.进程理解
1.进程的概念
我们大家应该都知道我们windows系统当中的任务管理器
程序被加载到内存变成进程的时候,操作系统会给每一个进程分配一个用来存放该进程的结构体对象的数据,方便操作系统对进程进行管理!
下面这个就是描述进程信息的结构体
至此操作系统成功将进程的属性用PCB对象描述好了,
因此操作系统对于进程的管理就变成了对PCB对象的管理
因此:
进程=内核数据结构(不仅仅是PCB对象)+可执行程序
因此,所有对进程的控制和操作都只和进程的PCB对象有关,和进程的可执行程序无关
只要你愿意,你可以把PCB对象放入任何数据结构中进行管理!
2.task_struct结构体独特的链接方式
请注意:
一个task_struct可以被连入多种数据结构中!!!
这一点很重要,因为我们以后还要介绍运行队列,
这就是在不改变task_struct已经形成的链表结构的同时
还可以将其放入队列当中的原因
3.task_struct内容分类(粗略的谈一下)
那么task_struct里面都是什么呢?
我们先来粗略的谈一下
关于这里的这个pc指针或者eip寄存器
我们介绍一下它的作用
这些内容我们以后会详细介绍的
你说了这么多,总得让我们见一见进程吧
下面我们先来看一下进程基础的相关操作
四.进程基础的相关操作
1.查看进程
先生成一个process可执行程序
ps ajx | head -1 && ps -ajx | grep 可执行程序名字
在这里我们先执行了一个可执行程序:process
然后查看这个进程
ps ajx | head -1 && ps -ajx | grep 可执行程序名字 | grep -v grep
2.杀死进程
刚才我们说了ctrl+c退出一个进程
有些时候ctrl+c并不可行(下面我们就会见到这种情况的)
此时就需要我们去使用
kill -9 进程的PID
来杀死指定的进程
五.进程PID
1.getpid()和getppid()
注意:pid_t的值都是正整数或0
下面我们来在代码当中查看一下process的进程ID和其父进程ID
while :; do ps ajx | head -1 && ps ajx | grep 可执行程序名字 | grep -v grep; sleep 1;done
这个shell命令可以死循环查看含有指定可执行程序名字的进程
每次while循环都会休眠1秒
按ctrl+c退出
根据进程ID查看对应进程的信息:
ps ajx | head -1 && ps ajx | grep 进程ID | grep -v grep
下面我们多次执行这个进程,发现:
2.fork()函数创建进程
1.fork()函数
2.演示
下面我们来演示一下
3.几点说明
1.进程的独立性
(任意)进程之间是具有独立性的,互相之间不能影响
即使父进程和子进程亲如父子,但是当我们的子进程和父进程都运行起来之后,
子进程挂了,代码也仍会存在,对父进程无影响
父进程挂了,代码也仍会存在,对子进程无影响
杀死父进程,子进程依然运行
不过此时因为父进程被杀死了,所以子进程无法通过ctrl+c退出
只能使用kill -9杀死子进程
杀死子进程,父进程依然运行,
右上方的窗口显示了子进程处于defunct(也就是关闭)的状态
说明子进程被杀死了,按ctrl+c后父进程可以正常退出
关于父子进程的话题,我们以后在介绍僵尸进程和孤儿进程的时候会进行详细说明的
在这里我们只需要知道:进程之间是具有独立性的,互相之间不能影响
2.关于fork函数返回值的几个问题
1.为何给父子进程的返回值是不同的?
通过fork函数的返回值区分父子进程,利用if else判断来让父子进程做不同的事情
2.fork函数为何会返回2次?
在fork函数内部,在执行到return语句之前,子进程已经被创建好了
又因为父子进程的代码是共享的
而且return语句本身也属于代码
所以return语句既会被父进程执行,也会被子进程执行
3.为何id作为同一个变量既可以表示父进程id,又可以表示子进程id呢?
这就涉及到写时拷贝的知识点了,先在这里提一下,以后我们还会提到的:
因此,我们可以得出:
在Linux中,可以用同一个变量名来表示不同的内存
4.创建多个子进程(观察进程的创建和退出的全过程)
下面我们创建多个子进程
观察一下进程的创建和退出的全过程
最后所有的子进程都退出了,只剩下一个父进程最后休眠了15秒之后才退出
这样我们就能够看到进程从创建到退出的全过程了
这里的子进程处于defunct(也就是关闭)的状态就表示该进程已经退出了
六.另一种查看进程的方法
1./proc
进程的信息可以通过 /proc 系统文件夹查看
ls /proc
查看具体某一个进程的信息:
ls /proc 进程id
下面我们用mycmd这个可执行程序来测试一下
我之前在Linux中的shell外壳与权限(包含目录文件的权限,粘滞位的来龙去脉)这篇博客中提到过链接文件
接下来我们还会见到链接文件
2.exe链接文件
不过这个进程就只能执行这一次了,当这个进程结束之后,就无法再执行了
当我把mycmd这个可执行程序删除之后,这个进程依旧再运行
但是这个exe执行的那个可执行程序已经显示deleted了
3.如何改变cwd呢?
我们可以使用chdir函数
下面我们来实验一下
当前是在这个路径下
我想让它到
/home/wzs/wzsdir/systemlearndir
这个路径下
下面我们来创建一个文件
加深一下对cwd和fopen函数的理解
发现test.txt的确被创建在了
/home/wzs/wzsdir/systemlearndir
这个路径下
七.总结
这篇博客我们主要介绍了
1.冯诺依曼体系结构
2.操作系统
3.进程的概念,task_struct结构体
4.进程基础的相关操作:查看进程,杀死进程,改变进程所在工作目录
5.进程PID,fork函数创建进程
以上就是Linux进程理解(冯诺依曼体系结构,操作系统,进程概念和基本操作)的全部内容,希望能对大家有所帮助!