第一章 温故而知新

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执行乱序

相关文章
相关标签/搜索