您的位置:首页 > 理论基础

【笔记】深入理解计算机系统

2014-06-28 10:37 288 查看
零.计算机系统漫游

1.程序被翻译成不同的格式

预处理阶段 (#include<stdio.h> 得到另一个C程序)
编译阶段
汇编阶段
链接阶段

2.处理器

从程序计数器PC指向的存储器读取指令,解释指令中的位,执行指令指示的简单操作,然后更新指向新程序计数器的下一条指令

3.CPU在指令的要求下可能会执行这些操作







3.上下文

操作系统保存进程运行所需的所有状态信息,这种状态就是上下文。(PC 寄存器堆当前值,以及主存的内容)

当操作系统决定从当前进程转移控制权到某个新进程时,就会进行上下文切换,即保存当前进程的上下文,恢复新进程的上下文,然后将控制权转移到新进程。

4. 虚拟存储器



九.虚拟存储器

1. 页表

将虚拟地址空间映射到物理地址空间

2. 动态存储器分配

动态存储器分配器维护着一个进程的虚拟存储器区域,成为堆。内核维护着一个变量brk,指向堆的顶部

动态存储器分配器,可以通过mmap或者munmap显示分配,还可以使用sbrk函数

void *sbrk(intptr_t incr) 将内核的brk指针增加incr来扩展或收缩堆

3.垃圾回收机制

标记 删除(Mark-Sweep)、

(对所有存活对象进行一次全局遍历来确定哪些对象可以回收,遍历的过程从根出发,找到所有可达对象,除此之外,其它不可达的对象就是垃圾对象,可被回收。整个过程分为两个阶段:标记阶段找到所有存活对象;清除阶段清除所有垃圾对象。)

引用计数算法

(优点:内存管理分配的开销分布于整个程序的运行期间。 提供一种类似栈分配方式,当对象的引用计数为0 时,将删除)

十一.系统级I/O

1. Unix I/O

每个进程开始时都有三个打开的文件:标准输入 标准输出 标准错误 STDIN_FILENO STDOUT_FILENO STDERR_FILENO
打开文件 int open(char *filename, int flags, mode_t mode);

umask(DEF_MODE);

fd = open("foo.txt", O_CREAT|O_TRUNC|O_WRONLY, DEF_MODE);

读写文件

ssize_t read(int fd, void *buf, size_t n);

ssize_t write(int fd, const void *buf, size_t n);

共享文件 (内核用三种相关的数据结构来表示已经打开的文件)

(1) 描述符表,每个打开的描述符表项指向文件表的一个表项
(2) 文件表,打开文件的集合由一张文件表来表示,所有的进程共享这张表。每个文件表的表项(当前的文件位置,引用计数,以及一个指向v-node表中对应表项的指针,内核不会删除这个文件表表项,知道它的引用计数为0)
(3) v-node表, 所有进程共享这张v-node表,每个表包括stat结构中的大多数信息



I/O重定向

int dup2(int oldfd, int newfd); //拷贝描述符表项



2. 标准I/O

标准库I/O将一个打开的文件模型化为一个流(stream),对于程序员,一个流就是一个指向类型为FILE结构的指针



十二.网络编程

1. 因特网连接

一个连接由它两端的套接字地址唯一确定,这对套接字地址叫做套接字对(socket pair)

2. Web服务器

Web服务器以两种不同的方式向客户端提供内容:

取一个磁盘文件并将它的内容放回给客户端。(静态内容)
运行一个可执行的文件,并将它的内容返回给客户端。(动态内容)

3. HTTP请求
一个HTTP请求是这样的:一个请求行,后面跟随零个或更多个请求报头,在跟随一个空的文本行来终止报头列表
<method><uri><version>
HTTP支持许多不同的方法,包括GET POST OPTIONS HEAD PUT DELETE TRACE。
GET / HTTP/1.1
host www.***.com

4. HTTP相应
<version> <status code> <status message>

十三.并发编程

控制逻辑流在时间上重叠,就是并发

1. 基于进程的并发服务器

void sigchld_hander(int sig) {
while (waitpid(-1, 0, WNOHANG) > 0) ;
return;
}
signal(SIGCHLD, sigchld_handler);

if (fork() == 0) {

close(listenfd);

...........

close(connfd);

exit(0);

}

2.
基于I/O多路复用的并发编程

使用seliect,使内核挂起进程,只有在一个或多个I/O事件发生后,才将控制返回给应用程序。 select处理类型为fd_set的集合(描述符集合),n位的掩码















3. 基于线程的并发编程
每个线程都有自己的线程上下文(线程ID, 栈,栈指针,程序计数器,通用目的寄存器,条件码),所有进程共享进程的整个虚拟地址空间,代码,数据,堆,共享库和打开的文件

(1). 线程执行模型



2. 分离线程

一个可结合的线程能够被其他线程收回资源和杀死,在被其他线程回收之前,它的存储器资源是不释放的。

一个分离的线程是不能被其他线程回收或杀死,它的存储器资源在它终止时由系统自动释放

int pthread_detach(pthread_t tid);

取一个磁盘文件并将它的内容放回给客户端。(静态内容)
运行一个可执行的文件,并将它的内容返回给客户端。(动态内容)

3. 初始化线程
pthread_once_t once_control = PTHREAD_ONCE_INIT;
int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));

2. Posix信号量

#include <semaphore.h>

int sem_init(sem_t *sem, unsigned int value);

int sem_wait(sem_t *s); //P(s)

int sem_post(sem_t *s) //V(s)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: