1、从Hello World提及缓存
#include<stdio.h> int main() { printf("Hello world\n"); return 0; }
一、程序为何要被编译器编译了以后才能够运行?安全
二、编译器在把C语言程序转换成能够执行的机器码的过程当中作了什么?怎么作的?多线程
三、最后编译出来的可执行文件里面是什么?除了机器码还有什么?他们怎么存放的,怎么组织的?并发
四、#include<stdio.h>是什么意思?把stdio.h包含进来是意味这什么?C语言库又是什么?他怎么实现的?函数
五、不一样的编译器和不一样的硬件平台以及不一样的操做系统,最终编译出来的结果同样吗?为何?spa
六、Hello World程序是怎么运行起来的?操做系统是怎么装载它的?它从哪儿开始执行,到哪儿结束?main函数以前发生了什么?main函数结束之后又发生了什么?操作系统
七、若是没有操做系统,Hello World能够运行吗?若是要在一台没有操做系统的机器上运行Hello World须要什么?应该怎么实现?线程
八、printf是怎么实现的?他为何能够有不定数量的参数?为何他可以在终端上输出字符串?指针
九、Hello World程序运行时,他在内存中是什么样子?code
2、万变不离其踪
一、北桥芯片主要协调CPU、内存和高速的图形设备;南桥芯片主要协磁盘、USB等低速设备
二、对称多处理器(SMP:Symmetrical Multi-Processing):简单地讲就是每一个CPU在系统中所处的地位和所发挥的功能都是同样的,是相互对称的。
三、多核处理器(Multi-Core Processer):将多个处理器合并在一块儿打包出售,这些被打包的处理器之间共享比较昂贵的缓存部件,只保留多个核心,能够视做SMP简化版。
四、操做系统做用:CPU调度(多道程序-->分时系统-->多任务系统);设备驱动;内存管理(直接使用物理内存-->分段-->分页)
3、线程基础
线程(Thread),有时被称为轻量级进程(Lightweight Process, LWP)是程序执行流的最小单元。一个标准的线程是由线程ID、当前指令指针(PC)、寄存器集合和堆栈组成。一般意义上,一个进程是由一个到多个线程组成,各个线程之间共享程序的内存空间(包括代码段、数据段、堆等)及一些进程级的资源(如打开文件和信号)。
一、多线程使用场景:a、某个操做可能会陷入长时间等候;b、某个操做是CPU密集型;c、程序逻辑是并发(下载);d、相比多进程,多线程共享效率更高
二、线程的私有空间:a、栈;b、线程局部存储;c、寄存器
三、线程的共享空间:a、全局变量;b、堆上的数据;c、函数里的静态变量;d、程序代码,任何线程都有权限读取并执行任何代码;e、打开的文件等资源
四、原子操做:单指令的操做称之为原子操做,由于不管如何,单条指令的执行都不会被打断。为了不出错,不少体系结构都提供了一些经常使用的原子指令。
4、线程安全
为了不多个线程同时读写同一个数据而产生不可预料的后果,咱们要将各个线程对同一个数据的访问同步(Synchronization)。所谓同步,即指在一个线程访问数据未结束的时候,其余线程不得对同一个数据进行访问。
经常使用的线程同步方式:a、二元信号量(Binay Semaphore)/信号量(Semaphore);b、互斥量(Mutex);c、临界区(Critical Section);d、读写锁(Read-Write Lock);e、条件变量(Condition Variable)。
可重入函数必须知足几个特色:a、不使用任何静态或局部的非const变量;b、不返回任何静态或全局的非const变量的指针;c、仅依赖与调用方提供的参数;d、不依赖任何单个资源的锁;e、不调用任何不可重入的函数。
5、Double-Check
volatile T*pInst = 0; T* GetInstance() { if(pInst == NULL) { lock(); if(pInst == NULL) { pInst = new T; } unlock(); } return pInst; }
上面的代码不是线程安全的,缘由有二:一、编译乱序;二、CPU执行乱序