赞
踩
如图,由于外设的读取速度是非常慢的(相对于内存),而CPU的运算速度非常快,经常会出现外设还未读取,cpu已经读取完成进度等待状态了。因此我们需要提前从外设里提取一部分数据存储在内存中,让内存为cpu提供数据。
在数据层面,外设一般不与cpu打交道,只和内存打交道
学习C语言的时候经常听到一句话,程序要被加载到内存里才能执行。其实就是由于计算机的体系结构决定的。
可执行程序被存储在磁盘上,磁盘属于一种外设,因此不会直接和cpu打交道,所以需要将程序先加载到内存上,让内存与cpu打交道!
常见的输入设备和输出设备有:
输入设备:键盘
、鼠标、话筒、摄像头、网卡、磁盘…
输出设备:显示器
、磁盘、音响…
介绍完计算机的体系结构,有如此多的硬件,包括输入设备和输出设备,那么如何将他们管理起来呢?
操作系统是一款进行软硬件资源管理的
软件
。
1、如何理解操作系统对硬件进行管理呢?
首先我们要知道,管理的本质就是对被管理的东西进行建模,举个例子:
一所学校应该如何管理学生?并不是进入了这所学校的大门就算是被管理了,我们知道只有我们的学籍信息出现在学校数据库里,我们才算是被学校管理了。
也就是说,学校管理的并不是我们这个实在的人,而是将我们的各种数据存储在学籍系统里,包括年龄、成绩等。是谁拿到我们的数据呢,是辅导员,显然这样更加高效合理。
操作系统也是采用这样的方式进行对软硬件的管理,即:
管理的本质:先描述再组织
2、操作系统为什么要对软硬件资源进行管理呢?
操作系统对下通过管理好软硬件资源的(手段),对上给用户提供良好(安全、稳定、高效、功能丰富)的执行环境(目的)。
3、操作系统会相信我们吗?
再举一个例子,银行帮助用户存取金钱,但银行是绝对不会信任任何人的,即银行不可能对我们开放金库。银行提供了窗口来为我们用户提供服务。
其中对应关系如下:
操作系统也是一样,操作系统为了保证自己的安全,是绝不会完全相信我们的。它同样预留了一些接口(系统调用)其实就是C函数。
用一张图更清晰的感受计算机的体系结构:
我们任何启动程序的行为,都是操作系统帮助我们转换为进程。
文件是由文件内容和文件属性决定的,进程则是由内核关于进程的数据结合 + 当前进程的代码和数据构成。
windows下这个结构体为pcb而在linux下这个结构体是task_struct
1、bash命令行解释器,本质上也是一个进程
2、命令行启动的所有程序,最终也会变成进程,而改该进程的父进程都为bash
启动程序:
如何创建一个进程?只要启动一个程序即创建了一个进程,如何查看这个进程呢?
使用以下命令可以查看名为 myfile 的进程。
ps axj | head -n1 && ps ajx | grep myfile | grep -v grep
其实每个进程都会一串标识数字,被叫做进程标识符,我们需要通过 系统调用getpid和getppid 来获取当前进程的进程标识符。使用时需要引入这两个头文件。
#include <sys/types.h>
#include <unistd.h>
先写一个死循环,让程序输出自己的pid和ppid,达到如图效果:
紧接着查询是否存在这两个进程:
得出结论:父进程确实存在且是bash。
fork系统调用:
系统调用函数fork也可以创建一个进程,并且可以在一个进程创建后在其中再创建一个子进程。
以下是一个参考代码:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(){
while(1){
int ret = fork();
if(ret == 0){
//子进程
}else{
//父进程
}
}
}
1、fork之后,执行流会被分为两个。
2、fork之后,谁先执行由调度器说了算。
3、fork之后,二者共享代码。
fork是如何看待代码和数据的呢?
进程在运行的时候,是具有独立性的!父子进程也是一样
代码:代码只读,二者会共享。
数据:当一个执行流尝试去修改数据的时候,OS会自动给我们当前进程触发写时拷贝。
如何理解fork有两个返回值的问题?
这个问题等我们学到进程地址空间再进行详细解析。
进程同样拥有状态,就像我们浏览应用经常会遇到卡顿等现象。这就与进程的状态息息相关。
进程状态:
在学习进程状态之前,我们必须要搞明白两个状态:
阻塞: 进程因为等待某种条件就绪,而导致的一种不推进的状态。
既然如此,阻塞一定是在等待某种资源(磁盘、显卡、外设等)就绪
因此需要等待某种资源的PCB就要维护在OS管理的不同设备的请求队列下排队!
挂起:
挂起状态如图所示,进程在等待某个资源的时候,若等待时间过长,会将代码和数据放入磁盘内。
进程是什么状态,一般也看这个进程在哪里排队
并且这个队列是由操作系统维护!
S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠,本质是一种阻塞状态。
D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。一般我们见到D状态是非常危险的。
T之后的状态不带 + ?
‘+’ 表示进程在前台进行,没有+表示在后台运行,不可以使用ctrl + c停止进程,需要使用kill命令杀死进程。
kill -9 pid
X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。
Z僵尸进程
我们为什么要使用进程?因为我们需要这个进程来帮我进行工作,通常我们关心结果,如果进程结束立马进入X状态退出进程,父进程就没有机会获得结果了,所以在LINUX下,进程彻底退出,会维持一个Z状态,方便后续父进程(OS)读取子进程退出的退出结果。
结语:
到这里本篇文章就结束了,希望对你理解linux 进程有些许帮助,若你觉得本文写的还不错,可以点赞+ 关注支持一下学者,我们下次见~~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。