CSAPP 读书笔记-第八章异常控制流

8.1.2 异常的类别

1. 中断

中断是异步发生的,是来自处理器外部的 I/O 设备的信号的结果。硬件中断不是由任何一条专门的指令造成的,从这个意义上来说它是异步的。

剩下的异常类型是同步发生的,是执行当前指令的结果。我们把这类指令叫做故障指令。

2. 陷阱和系统调用

陷阱是有意的异常,是执行一条指令的结果。就像中断处理程序一样,陷阱处理程序将控制返回到下一条指令。陷阱最重要的用途是在用户程序和内核之间提供一个像过程一样的接口,叫做系统调用。

3. 故障

当故障发生时,处理器将控制转移给故障处理程序。如果处理程序能够修正这个错误情况,它就将控制返回到引起故障的指令,从而重新执行它。否则,处理程序返回到内核中的 abort 例程,abort 例程会终止引起故障的应用程序。

4. 终止

终止处理程序从不将控制返回给应用程序。

阅读更多

CSAPP 读书笔记-第七章链接

7.1 编译器驱动程序

大多数编译系统提供编译器驱动程序(compiler driver),它代表用户在需要时调用语言预处理器、编译器、汇编器和链接器。比如,要用 GNU 编译系统构造示例程序,我们就要通过在 shell 中输入下列命令来调用 GCC 驱动程序:

1
gcc -Og -o prog main.c sum.c

驱动程序首先运行 C 预处理器(cpp),它将 C 的源程序 main.c 翻译成一个 ASCII 码的中间文件 main.i

接下来,驱动程序运行 C 编译器(ccl),它将 main.i 翻译成一个 ASCII 汇编语言文件 main.s

然后,驱动程序运行汇编器(as),它将 main.s 翻译成一个可重定位目标文件(relocatable object file)main.o

最后,驱动程序运行链接器程序 ld,将 main.osum.o 以及一些必要的系统目标文件组合起来,创建一个可执行目标文件(executable object file)prog

阅读更多

CSAPP 读书笔记-第六章存储器层次结构

6.1 存储技术

6.1.1 随机访问存储器

  1. 静态 RAM

用来做高速缓存存储器。

SRAM 将每个位存储在一个双稳态的存储器单元里。非常稳定,只有两个状态,正好表达二进制,但是造价高,功耗大。

  1. 动态 RAM

用来做内存。

DRAM 将每个位存储为对一个电容的充电。

DRAM 存储器单元对干扰非常敏感。暴露在光线下会导致电容电压改变。

阅读更多

CSAPP 读书笔记-第五章优化程序性能

十几年前我看不懂、看不下去,没想到现在还是看不懂、看不下去。第五章把常见的(减少函数调用等)、不常见的(循环展开等)优化手段从指令层面做了深度剖析,授人以鱼的同时也授人以渔,写得真的是好!

但是真得是要花大力气才能理解透彻,要不断地实践加深记忆,才能牢牢掌握这些知识。无奈我一个应用(业务)码农,实在是难得有这种机会,所以只做简单的要点摘要作罢。

编写高效程序需要做到以下几点:第一,我们必须选择一组适当的算法和数据结构。第二,我们必须编写出编译器能够有效优化以转换成高效可执行代码的源代码。

5.4 消除循环的低效率

一个循环天然地带有两个反复执行的语句,所以尽量不要在这两个语句中插入耗时的表达式——函数调用等。

阅读更多

CSAPP 读书笔记-第一章计算机系统漫游

第一章是对整书后续章节内容的高度概括。全书以经典的 Hello World 程序开篇,概括了从源码到可执行文件的编译过程;然后深入硬件底层,描述了一台计算机典型的物理构成;最后,抛出抽象的概念,说明是如何通过操作系统、进程、虚拟内存、文件这些抽象概念管理底层硬件的。

1.2 程序被其他程序翻译成不同的格式

1
gcc -o hello hello.c

用此例揭示了编译的四个步骤:

  • 预处理阶段(cpp),hello.c -> hello.i
  • 编译阶段(ccl),hello.i -> hello.s
  • 汇编阶段(as),hello.s -> hello.o
  • 链接阶段(ld),printf.o + hello.o -> hello
阅读更多

我身边的这位“鑫爷”

最近几周接手了一个同事的大量代码,其中不合理的地方多到我实在不吐不快。

这位同事平日里看着兢兢业业,能说会道,常打交道的同事们都喊他一句“鑫爷”。可是我看了他的代码之后,这个“爷”字我是无论如何也是喊不出来了。

阅读更多

一种低成本视频直播(轮播)解决方案

0. 概述

影视剧的直播,有其特殊性:

  1. 直播内容是“静态的”。直播源通常是预制的视频文件,而非实时通过摄像头采集的数据。
  2. 没有主播,所以也就没有主播和观众的互动需求。所以对延时(主播和观众的时间差)要求不高,只要保证所有观众端具有差不多的播放进度即可。

所以相比摄像头开播的直播,影视剧直播的技术方案有可简化的余地:

  1. 把视频文件预先转换成目标格式,避免推流过程中的编解码(当然这里只考虑为观众提供原始码率,不需要转码的情况)。
  2. 把视频文件切割成多个时间长度为几秒钟的小视频文件,依次轮播。当新用户进入时,使其从当前序号的视频文件播放即可——同其它观众的时间差不超过此文件的时长。
阅读更多

使 Sanic 后端支持 CORS

1. 源端消除 Preflight

Preflight(预检请求)是指在跨源发出用户请求前,预先发出一个 OPTIONS 请求,查询服务端是否允许从此源站的请求。

Restful 规范是“罪魁祸首”。因为跨域 fetch 时,application/json 类型的 Content-Type 必然会触发 Preflight。

只有满足简单请求fetch,才不会触发 Preflight:

阅读更多

利用 midea_ac_lan 开源库控制美的空调

前言

美的智能家居平台的接口是非开放的。不管是在 HomeAssistant 还是 HomeBridge 中接入美的设备,都是靠伟大无私的开源社区提供解决方案。

在之前我自己的基于 Python 实现的智能家居控制系统 里,我用到的是 midea-ac-py

由于美的空调的 token、key 在每次重新供电时都会变化,而这个库没有将 discover 功能集成进来——库作者额外提供了一个命令行工具(
midea-msmart
)发现局域网内的美的设备,导致更新 token 流程的自动化程度不高,每次都要人工复制。

我曾经尝试把 midea-msmart 集成进我的系统,通过可编程方式更新 token,总会遇到各种奇怪问题,比如帐密验证失败、超时等等,所以一直在寻找可替代库。终于让我发现了 midea_ac_lan

阅读更多

2022年终总结和2023年展望

2022 年迎来转机

上半年工作上按部就班。无休止地裁员反倒给了我们这些暂时留下来的人休息的机会——毕竟谁都不知道自己会不会是下一个,还加什么班呢?

我也一样,每天准点上下班。

所以晚上、周末的空闲时间多了,年初时候定下的 2022 年学习目标进展地就比较顺利。

高优先级的俩目标,系统学习 React.js 和 Sanic.py,我完成了。并且学以致用,一直在持续开发、维护、重构我的两个小网站。对其常规的使用方式上,也算是纯熟了。

“机会总是留给有准备的人的”。我再次因为笃信这句格言而受益。

阅读更多