第一章:温故而知新
过度优化的问题:
我们知道volatile关键字可以阻止过度优化,因为它可以完成两件事:
- 阻止编译器为了提高速度将一个变量缓存到寄存器而不写回
- 阻止编译器调整操作volatile变量的指令顺序
然而,在优化这一块,不仅编译器会做优化,CPU也会做优化。volatile就管不着了CPU了。
经典的例子当然是单例模式。单例模式有一种常规的解决方案是DCL,也就是双重检查锁,但是在C++中new的步骤有是分为三个步骤:分配内存,调用构造函数,将内存地址用指针保存下来。CPU就要来搞怪,将第二步第三步乱个序。
一种解决方案是:调用CPU提供的barrier指令阻止将barrier指令之前的代码交换到barrier之后。但是这种方案不具有可移植性。部分实现代码如下:
if(!pInst){lock();if(!pInst){T* temp = new T;barrier();pInst = temp;}unlock();
}
线程:
是程序执行流的最小单元。通常意义上,一个进程由多个线程组成,各个线程之间共享程序的内部空间(包括代码段,数据段,堆等)及一些进程级的资源(如打开文件和信号)
线程的访问权限:
线程调度与优先级
- 运行(Running):此时线程正在执行
- 就绪(Ready):此时线程可以立刻运行,但CPU已经被占用
- 等待(Waiting):此时线程正在等待某一件事件发生,无法执行
可抢占线程和不可抢占线程
线程在用尽时间片之后会被强制剥夺继续执行的权利,而进入就绪状态,这个过程叫做抢占,即之后执行的别的线程抢占了当前线程。
在早期的一些系统中,线程是不可抢占的。线程必须手动发出一个放弃执行的命令,才能让其他的线程得到执行。可以避免一些因为抢占式线程里调度时机不确定而产生的问题。非抢占式线程已经十分少见
参考文章:《程序员的自我修养》笔记_程序员的自我修养 写时复制-CSDN博客