-
Notifications
You must be signed in to change notification settings - Fork 381
/
Copy pathReadme.md
73 lines (37 loc) · 5.53 KB
/
Readme.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# 操作系统概论
操作系统是一种计算机软件。在硬件之上,应用程序之下。主要功能就是管理底下的计算机硬件,并为上层的应用程序提供统一的接口。
![img](https://camo.githubusercontent.com/9f8cbe895e7729fc61e18424f2edb7b23ef9d6f3/687474703a2f2f6974666973682e6e65742f486f6d652f4d6f64756c65732f496d616765732f6974666973685f34343836395f302e6a7067)
**系统调用**:应用程序直接调用操作系统提供的接口 如write 函数
**库函数调用**:应用程序通过一些库函数直接调用 如 fwrite
## 内核态和用户态
操作系统为了管理内存。将内存分为**内核空间**(内核态)和**用户空间**。内存空间和用户空间之间有隔离。
**用户空间即上层应用程序的活动空间**,应用程序的执行必须依托于内核提供的资源,包括CPU资源、存储资源、I/O资源等。为了使上层应用能够访问到这些资源,内核必须为上层应用提供访问的接口:即系统调用
![img](https://images2015.cnblogs.com/blog/431521/201605/431521-20160523163606881-813374140.png)
内核从本质上看是一种软件——控制计算机的硬件资源,并提供上层应用程序运行的环境。
shell就是外壳。类似一种胶水的功能。可以通过shell访问内核。
内核态与用户态是指CPU的运行状态(即特权级别),每个进程的每种CPU状态都有其运行上下文,运行上下文就包括了当前状态所使用的空间,CPU访问的逻辑地址(即空间)通过地址映射表映射到相应的物理地址(即物理内存)。在Linux系统中,进程的用户空间是独立的,而内核空间是公用的,进程切换时,用户空间切换,内核空间不变。
对于多数CPU而言,处于内核态时,可以访问所有地址空间,而处于用户态时,就只能访问用户空间了。
## 用户态和内核态切换
操作系统的资源是有限的,如果访问资源的操作过多,必然会消耗过多的资源,而且如果不对这些操作加以区分,很可能造成资源访问的冲突。
为了减少有限资源的访问和使用冲突,Unix/Linux的设计哲学之一就是:对不同的操作赋予不同的执行等级,就是所谓特权的概念
Linux操作系统中主要采用了0和3两个特权级,分别对应的就是内核态和用户态。运行于用户态的进程可以执行的操作和访问的资源都会受到极大的限制,而运行在内核态的进程则可以执行任何操作并且在资源的使用上没有限制。很多程序开始时运行于用户态,但在执行的过程中,一些操作需要在内核权限下才能执行,这就涉及到一个从用户态切换到内核态的过程
![img](https://images2015.cnblogs.com/blog/431521/201605/431521-20160523210140147-1668637440.gif)
## 库函数调用和系统调用的区别
![这里写图片描述](http://img.blog.csdn.net/20170117211419709?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTEZfMjAxNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
系统调用(英语:system call),指运行在用户空间的应用程序向操作系统内核请求某些服务的调用过程。 系统调用提供了用户程序与操作系统之间的接口。一般来说,系统调用都在内核态执行。由于系统调用不考虑平台差异性,由内核直接提供,因而移植性较差(几乎无移植性)。
库函数(library function),是由用户或组织自己开发的,具有一定功能的函数集合,一般具有较好平台移植性,通过库文件(静态库或动态库)向程序员提供功能性调用。程序员无需关心平台差异,由库来屏蔽平台差异性。
| 函数库调用 | 系统调用 |
| ----------------------------- | ----------------------- |
| 平台移植性好 | 依赖于内核,不保证移植性 |
| 调用函数库中的一段程序(或函数) | 调用系统内核的服务 |
| 一个普通功能函数的调用 | 是操作系统的一个入口点 |
| 在**用户空间**执行 | 在**内核空间**执行 |
| 它的运行时间属于“用户时间” | 它的运行时间属于“系统”时间 |
| 属于过程调用,调用开销较小 | 在用户空间和内核上下文环境间切换,开销较大 |
| 库函数数量较多 | UNIX中大约有90个系统调用,较少 |
| 典型的C函数库调用:printf scanf malloc | 典型的系统调用:fork open write |
![clip_image002](http://blog.chinaunix.net/attachment/201207/11/27105712_13419741441gpp.gif)
读写IO通常是大量的数据(这种大量是相对于底层驱动的系统调用所实现的数据操作单位而言),使用库函数调用可以大大减少系统调用的次数。这是因为缓冲区技术。在用户空间和内核空间,对文件操作都使用了缓冲区,当内核缓冲区写满之后或写结束之后才将内核缓冲区内容写到文件对应的硬件媒介中。
**不带缓冲指的是每个read和write这些文件I/O操作都调用的是系统调用,属于内核态的操作**
诸如fread和fwrite这些标准I/O操作属于用户态操作,具体是库函数的实现,需要借助用户缓冲区来实现
更多内容可以参考 [操作系统](https://github.com/xianyunyh/studynotes/tree/master/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F)